Python 定义参数过多的函数,无法遵守 PEP8 标准

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24988162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:34:21  来源:igfitidea点击:

Define functions with too many arguments to abide by PEP8 standard

pythonpep8

提问by Sudip Kafle

I have defined a function with a long list of arguments. The total characters in definition is above 80 and doesn't abide by PEP8.

我定义了一个带有一长串参数的函数。定义中的总字符数在 80 以上,不符合 PEP8。

def my_function(argument_one, argument_two, argument_three, argument_four, argument_five):

What can be the best approach to avoid horizontal scrolling?

避免水平滚动的最佳方法是什么?

采纳答案by BrenBarn

An example is given in PEP 8:

PEP 8 中给出了一个示例:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):

So that is the official answer. Personally I detest this approach, in which continuation lines have leading whitespace that doesn't correspond to any real indentation level. My approach would be:

所以这是官方的答案。我个人讨厌这种方法,其中连续行的前导空格与任何实际缩进级别都不对应。我的方法是:

class Rectangle(Blob):

    def __init__(
        self, width, height,
        color='black', emphasis=None, highlight=0
    ):

. . . or just let the line run over 80 characters.

. . . 或者让该行超过 80 个字符。

回答by kylie.a

def my_function(argument_one, argument_two, argument_three, 
                argument_four, argument_five):

回答by RayLuo

Personally I also used to come up with the same solution as @BrenBarn 's second style. I like its way to properly represent the indentation of function parameters AND its implementation, albeit that "unhappy face" is somewhat unusual to some other people.

我个人也曾经想出与@BrenBarn 的第二种风格相同的解决方案。我喜欢它正确表示函数参数的缩进及其实现的方式,尽管“不高兴的脸”对其他人来说有些不寻常。

Nowadays, PEP8specifically gives an example for such case, so perhaps the mainstream is going to adapt that style:

如今,PEP8专门为这种情况举了一个例子,所以也许主流会采用这种风格:

# More indentation included to distinguish this from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

回答by Rotareti

For Python code that uses type annotations, I suggest this:

对于使用类型注释的Python 代码,我建议这样做:

def some_func(
    foo: str,
    bar: str = 'default_string',
    qux: Optional[str] = None,
    qui: Optional[int] = None,
) -> List[str]:
    """
    This is an example function.
    """
    print(foo)
    ...

If you use yapfyou can use these options in .style.yapf:

如果您使用yapf,您可以在.style.yapf以下位置使用这些选项:

[style]
dedent_closing_brackets = true
split_arguments_when_comma_terminated = true

回答by Ben

I personally like to line up the params one-per-line starting with the open parentheses and keeping that indent. flake8seems happy with it too.

我个人喜欢从左括号开始一行一行地排列参数并保持缩进。flake8似乎也很满意。

def guess_device_type(device_name: str,
                      username: str=app.config['KEY_TACACS_USER'],
                      password: str=app.config['KEY_TACACS_PASS'],
                      command: str='show version') -> str:
    """Get a device_type string for netmiko"""

回答by BPL

I find myself this way to be quite interesting:

我发现自己这样很有趣:

def my_function(
        argument_one, argument_two, argument_three,
        argument_four, argument_five
):
    ...

it allows code-folding to reveal the function signatures quite easily, for instance, consider the below snippet:

它允许代码折叠很容易地显示函数签名,例如,考虑以下代码片段:

def my_function(
        argument_one, argument_two, argument_three,
        argument_four, argument_five
):
    s1 = 1
    s2 = 2
    if s1 + s2:
        s3 = 3


def my_other_function(argument_one, argument_two, argument_three):
    s1 = 1
    s2 = 2
    if s1 + s2:
        s3 = 3

This way allows to code-folding the whole file and seeing all functions/signatures at once, ie:

这种方式允许对整个文件进行代码折叠并一次查看所有功能/签名,即:

enter image description here

在此处输入图片说明

回答by Philippe Fanaro

1. What I would recommend

1. 我会推荐什么

Even though it makes the function more verbose, for more than one argument, I think this is best — the example below is from Python—:

即使它使函数更加冗长,对于不止一个参数,我认为这是最好的——下面的例子来自Python——:

def my_function(
    argument_one, 
    argument_two, 
    argument_three,
    argument_four, 
    argument_five,
):
    ...

2. Why?

2. 为什么?

  1. Having each argument on one line makes it very simple to use git diffs, since changing onevariable will only show thatchange. If you have more than one argument on each line, it's gonna be more visually annoying later.
    • Notice that the trailing comma after the last argument makes it easier to add or remove an argument later, while also conforming to the PEP 8's Trailing Comma Convention, and yielding a better git difflater.
  2. One of the reasons I reallydislike the "align the arguments with the opening parenthesis" paradigm is that it doesn't yield easily maintanable code.
    • Kevlin Henney explains it isa bad practice in his ITT 2016 - Seven Ineffective Coding Habits of Many Programmers lecture (around 17:08).
    • The major reason it is a bad practice is that if you change the name of the function (or if it is too long), you're going to have to re-edit the spacing on allthe arguments' lines, which is not at all scalable, though it may be (sometimes) (subjectively) prettier.
    • The other reason, closely related to the one immediately above, is about metaprogramming. If the codebase becomes too big, you will eventually find yourself needing to program changes to the code file itself, which might become hellif the spacing on arguments is different for each function.
  3. Most editors, once the parentheses are open and you press enter, will open a new line with a tab and shove the closing parenthesis to the next line, untabbed. So, formatting the code this way is very quick and kind of standardized. For instance, this formatting is very common in JavaScriptand dart.
  4. Lastly, if you think having each argument is too unwieldy because your function might have a lotof arguments, I would say that you're compromising easy formatting of your code due to rare exceptions.
    • Don't legislate by exceptions.
    • If your function has a lotof arguments, you're probably doing something wrong. Break it into more (sub)functions and (sub)classes.
  1. 将每个参数放在一行上使得使用git diffs变得非常简单,因为更改一个变量只会显示更改。如果每一行都有多个论点,那么后面会在视觉上更烦人。
    • 请注意,最后一个参数后面的尾随逗号使以后添加或删除参数更容易,同时也符合PEP 8 的尾随逗号约定,并在git diff以后产生更好的结果。
  2. 真的不喜欢“将参数与左括号对齐”范式的原因之一是它不会产生易于维护的代码
    • Kevlin Henney在他的 ITT 2016 - 很多程序员的七种无效编码习惯讲座(大约 17:08)中解释说这一种不好的做法。
    • 这是一个不好的做法的主要原因是,如果您更改函数的名称(或者它太长),您将不得不重新编辑所有参数行上的间距,这不是在所有可扩展的,虽然它可能(有时)(主观上)更漂亮。
    • 另一个原因,与上面的一个密切相关,是关于元编程。如果代码库变得太大,您最终会发现自己需要对代码文件本身进行编程更改,如果每个函数的参数间距不同,这可能会变得很糟糕
  3. 大多数编辑器,一旦打开括号并按下enter,将打开一个带有制表符的新行,并将右括号推到下一行,不带制表符。因此,以这种方式格式化代码非常快速且标准化。例如,这种格式在JavaScript和 中很常见dart
  4. 最后,如果您认为每个参数都太笨拙,因为您的函数可能有很多参数,我会说由于罕见的例外,您正在损害代码的简单格式。
    • 不要通过例外来立法
    • 如果你的函数有很多参数,你可能做错了什么。将其分解为更多(子)函数和(子)类。

3. Anyway...

3. 无论如何...

A good convention is better than a bad one, but it's much more important to enforce one than be unnecessarily picky about them.

一个好的约定好过一个坏的约定,但执行一个约定比对它们不必要地挑剔要重要得多

Once you've decided to use a standard, share your decision with your colleagues and use an automated formatter— for example, Prettieris a popular choice for JavaScriptin VS Code— to enforce it consistently, diminishing the need of manual editing.

一旦您决定使用标准,请与您的同事分享您的决定并使用自动格式化程序(例如,PrettierJavaScriptin的流行选择)以VS Code一致地执行它,减少手动编辑的需要。