用Pythonic的方式编写具有大量参数的函数/方法

22

想象一下:

def method(self, alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, kappa):
    pass

这行超过了79个字符,那么有什么Pythonic的方法可以多行书写吗?


6
考虑将参数分组为具有内聚数据的类。 - manifest
我了解 *args 的用法,但是我无法以这种方式分组参数,因为我使用的是 Python 的一个子集,不支持这种语法。 - Htechno
9个回答

34

您可以在括号(或方括号)内包含换行符,例如:

def method(self, alpha, beta, gamma, delta, epsilon, zeta,
                 eta, theta, iota, kappa):
    pass

(当然,包含的空格量取决于您)

但在这种情况下,您还可以考虑

def method(self, *args):
    pass

并且/或者

def method(self, **kwargs):
    pass

根据你如何使用参数(以及你想要函数被调用的方式)而定。


*args**kwargs再加一分。 - gomad
+1 多行代码使用括号。我花了一段时间才弄明白这个技巧,很多初学者也不知道它的方便之处。告别丑陋的 ! - manifest

23

我认为“Pythonic”的答案不仅仅涉及语法问题。向一个方法传递如此多的参数表明你的对象模型可能存在问题。

  1. 首先,你真的需要向这个方法传递那么多参数吗?也许这表明这项工作可以在其他地方更好地完成(由已经访问变量的对象完成)?

  2. 如果这确实是最好的地方,则可以通过self将其中一些参数作为该对象本身的实例变量提供吗?

  3. 如果不行,是否可以重新定义父对象的职责以包括它们?

  4. 如果不行,是否可以将任何单个参数封装到一个组合对象中,以规范它们之间的关系?如果任何参数有共同之处,那么应该是可行的。


9

我将后续行缩进2个级别:

def method(self, alpha, beta, gamma, delta, epsilon, zeta, eta,
        theta, iota, kappa):
    pass

5
+1并接受,因为回答了我的问题,假设我不是白痴,并且该解决方案兼容使用空格和制表符进行缩进。 - Htechno
这可能也回答了关于如何使用collection.abc中的概念来格式化参数和返回类型规范的问题,通常需要很多空间。 - Wolf

2
我会这样写。
def method(
    self, alpha, beta, gamma, delta, epsilon,
    zeta, eta, theta, iota, kappa
):
    pass

我认为它看起来漂亮干净。

1

当输入数字79时,我会在第一次出现的开括号处进行拆分,就像这样:

def method(self, alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota,
           kappa):

当名称过长无法放置在开括号后面时,我会这样做:

x.long_function_is_long(
    long_argument_is_loooooooooooooooooooooooooooooooooooooooong,
    longer_argument_is_looooooooooooooooooooooooooooooooooooooooonger
)

1
另一种选择是通过字典传递参数。

0

如果你有一个函数需要传递很多变量作为参数,你最后需要担心的事情就是缩进。


2
这并不算是一个答案,对吗? - ire_and_curses
3
我非常想点赞这个,但是呃... 应该发表在评论区。 - Shog9

0

为了可读性,当我有长名称时,我会这样做:

    file = load_sftp_file( SERVER_SFTP_HOST,
                           SERVER_SFTP_USER,
                           SERVER_SFTP_PASSWORD,
                           SERVER_SFTP_PRIVATE_KEY,
                           SERVER_SFTP_PATH,
                           FTP_DIR,
                           specific_filename=self.get_filename())

-4

我通常这样做,不知道是否最好,但它能够工作。由于我必须分割行,所以我让它们长度相等(如果可以的话):

def method(self, alpha, beta, gamma, delta, epsilon, \
                 zeta, eta, theta, iota, kappa):
    pass

此外,由于参数数量较多,我建议像David一样使用*args

4
在Python中,反斜杠字符是不必要的。使用圆括号进行分组允许代码跨多行 - 这在PEP 8 http://www.python.org/dev/peps/pep-0008/中指出。 - Ben Hayden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接