Coding style 有什么理由不总是使用关键字参数吗?

Coding style 有什么理由不总是使用关键字参数吗?,coding-style,python,Coding Style,Python,在开始使用python之前,我从一些Objective-C/Cocoa书籍开始。我记得,大多数函数都要求显式声明关键字参数。直到最近我才完全忘记了这一点,只是在Python中使用了位置参数。但是最近,我遇到了一些错误,这些错误是由不正确的位置引起的——它们是一些鬼鬼祟祟的小东西 让我思考——一般来说,除非有特别需要非关键字参数的情况——有什么好的理由不使用关键字参数吗?即使对于简单的函数,也总是使用它们被认为是不好的风格吗 我觉得,由于我的50行程序中的大多数都定期扩展到500行或更多行,如果我

在开始使用python之前,我从一些Objective-C/Cocoa书籍开始。我记得,大多数函数都要求显式声明关键字参数。直到最近我才完全忘记了这一点,只是在Python中使用了位置参数。但是最近,我遇到了一些错误,这些错误是由不正确的位置引起的——它们是一些鬼鬼祟祟的小东西

让我思考——一般来说,除非有特别需要非关键字参数的情况——有什么好的理由不使用关键字参数吗?即使对于简单的函数,也总是使用它们被认为是不好的风格吗

我觉得,由于我的50行程序中的大多数都定期扩展到500行或更多行,如果我习惯于总是使用关键字参数,那么随着代码的增长,代码将更易于阅读和维护。有什么理由不这样吗

更新:


我得到的总体印象是,这是一种风格偏好,有许多好的论点,它们通常不应该用于非常简单的论点,但在其他方面与好的风格是一致的。在接受之前,我只想澄清一下——这种方法是否会产生任何特定的非风格问题——例如,严重的性能问题

好吧,我有几个理由不这么做

如果您的所有参数都是关键字参数,则会增加代码中的噪音,并且可能会使哪些参数是必需的,哪些是可选的


还有,如果我必须使用你的代码,我可能会杀了你!!(只是开玩笑),但每次都必须键入所有参数的名称。。。没那么有趣。

当Python内置的
compile()
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。似乎没有明显的性能影响(如果有的话)


现在,如果让函数只接受关键字参数(而不是在调用时使用关键字传递位置参数,这是允许的),那么是的,这会很烦人。

有时候,事情应该很简单,因为它们很简单


如果您总是强制您在每次函数调用中使用关键字参数,很快您的代码将无法读取。

仅提供一个不同的参数,我认为在某些情况下命名参数可能会提高可读性。例如,想象一个函数在您的系统中创建一个用户:

create_user("George", "Martin", "g.m@example.com", "payments@example.com", "1", "Radius Circle")
根据该定义,这些值可能意味着什么并不清楚,即使它们都是必需的,但是对于命名参数,它总是显而易见的:

create_user(
    first_name="George",
    last_name="Martin",
    contact_email="g.m@example.com",
    billing_email="payments@example.com",
    street_number="1",
    street_name="Radius Circle")

除了代码的清晰性和可读性之外,没有任何理由不使用关键字参数。是否使用关键字的选择应基于在阅读代码时关键字是否添加了其他有用信息

我遵循以下一般规则:

  • 如果很难从函数名推断参数的函数(名称),请按关键字传递(例如,我不希望代码中有
    text.splitlines(True)
  • 如果很难推断参数的顺序,例如,如果您有太多的参数,或者当您有独立的可选参数时,请通过关键字传递(例如
    funkyplot(x,y,None,None,None,None,None,None,'red')
    看起来并不特别好)
  • 如果参数的目的是显而易见的,千万不要通过关键字传递前几个参数。你看,
    sin(2*pi)
    sin(value=2*pi)
    好,这同样适用于
    绘图(x,y,z)
  • 在大多数情况下,稳定的强制参数是位置参数,可选参数是关键字

    性能上也可能存在差异,因为在每个实现中,关键字参数都会稍微慢一点,但考虑到这通常是一个过早的优化,并且结果不会很显著,我认为这对决策来说并不重要

    更新:非风格问题

    关键字参数可以做位置参数所能做的一切,如果您正在定义一个新的API,除了可能的性能问题之外,没有任何技术上的缺点。但是,如果将代码与现有元素组合,则可能会出现一些小问题

    考虑以下几点:

    • 如果您让函数接受关键字参数,那么它将成为接口的一部分。 不能将函数替换为具有相似签名但对同一参数具有不同关键字的函数
    • 您可能希望在函数上使用decorator或另一个实用程序,该实用程序假定函数采用位置参数。未绑定方法就是此类实用程序的一个例子,因为它们总是在将第一个参数作为位置读取后将其作为位置传递,因此
      cls.method(self=cls\u实例)
      即使定义中有参数
      self
      ,也不起作用

    如果您设计好API并记录关键字参数的使用,这些都不是真正的问题,尤其是如果您设计的东西不应该与已经存在的东西互换。

    我记得读过一篇关于UNIX程序中“选项”的非常好的解释:“选项是可选的,程序应该能够在没有任何选项的情况下运行”

    同样的原则也可以应用于Python中的关键字参数。
    此类参数应允许用户“自定义”函数调用,但函数应该能够在没有任何隐式关键字-值-参数对的情况下调用

    当参数的含义显而易见时,我看不到使用关键字参数的目的

    我可以看到的一个缺点是,您必须为所有内容考虑一个合理的默认值,并且在许多情况下可能没有任何合理的默认值
    def logarithm(x=None):
        if x is None:
            raise TypeError("You can't do log(None), sorry!")
    
    def test(x, y):
        print "x:", x
        print "y:", y
    
    test(y=4, x=1)
    
    x: 1
    y: 4
    
    randint(low, high=None, size=None)    
    Return random integers x such that low <= x < high.
    If high is None, then 0 <= x < low.
    
    def square_sum(*params):
        sq_sum = 0
        for p in params:
            sq_sum += p*p
        return sq_sum
    
    testing(arg = 20, 56)
    
    SyntaxError: non-keyword arg after keyword arg