【问题标题】:Why does Pylint object to single-character variable names?为什么 Pylint 反对单字符变量名?
【发布时间】:2014-02-17 16:08:02
【问题描述】:

我仍然习惯于 Python 约定并使用 Pylint 使我的代码更加 Pythonic,但我对 Pylint 不喜欢单字符变量名这一事实感到困惑。我有几个这样的循环:

for x in x_values:
   my_list.append(x)

当我运行pylint 时,我得到Invalid name "x" for type variable (should match [a-z_][a-z0-9_]{2,30}——这表明一个有效的变量名的长度必须在 3 到 31 个字符之间,但我已经查看了 PEP8 naming conventions 并且我没有没有看到任何关于单个小写字母的明确内容,但我确实看到了很多使用它们的示例。

我在 PEP8 中是否缺少某些东西,或者这是 Pylint 独有的标准?

【问题讨论】:

    标签: python pylint naming-conventions


    【解决方案1】:

    关于 gurney alex noted 的更多细节:你可以告诉 Pylint 为 variable names 做例外处理(你小指发誓)即使少于三个字符也非常清楚。在[FORMAT] 标头下查找或添加到您的 pylintrc 文件:

    # Good variable names which should always be accepted, separated by a comma
    good-names=i,j,k,ex,Run,_,pk,x,y
    

    这里的pk(主键),x,y是我添加的变量名。

    【讨论】:

    • 这是最好的答案。
    • pylint 1.8.3 中似乎不起作用。 pylint.pycqa.org/en/1.8/user_guide/options.html
    • 我真正想要的是让 pylint 接受(根据要求)在理解中使用的短变量。比较 return [customer_address for customer_address in thing.get_customer_addresses() if customer_address.is_proper()]return [a for a in thing.get_customer_addresses() if a.is_proper()] 我声称后者更清楚,因为从上下文中可以明显看出。一般来说,变量长度应该与变量的范围相关。
    • 为了帮助 VS Code 用户,将此添加到 settings.json 文件中以正确配置 pylint:"python.linting.pylintArgs": ["--good-names=i,j,k,ex,Run,_,pk,x,y,z,e"]
    【解决方案2】:

    Pylint 不仅检查 PEP8 建议。它也有自己的建议,其中之一是变量名称应该是描述性的,并且不能太短。

    您可以使用它来避免这样的短名称:

    my_list.extend(x_values)
    

    或者调整 Pylint's configuration 告诉 Pylint 什么变量名是好的。

    【讨论】:

    • 使用_ 保存临时值是反模式。下划线变量表示不相关/丢弃的值,不是临时赋值,如ix。此外,在解释器中,保存最后一个表达式的最后一个值具有特殊意义。
    【解决方案3】:

    在强类型语言中,单字母名称变量可以是ok-ish,因为您通常会在变量声明或函数/方法原型中获得名称旁边的类型:

    bool check_modality(string a, Mode b, OptionList c) {
        ModalityChecker v = build_checker(a, b);
        return v.check_option(c);
    }
    

    在 Python 中,你不会得到这些信息,所以如果你写:

    def check_modality(a, b, c):
        v = build_checker(a, b)
        return v.check_option(c)
    

    对于该函数可以做什么、如何调用以及返回什么,您完全没有给维护团队留下任何线索。所以在 Python 中,你倾向于使用描述性的名称:

    def check_modality(name, mode, option_list):
        checker = build_checker(name, mode)
        return checker.check_option(option_list)
    

    你甚至可以添加一个文档字符串来解释这些东西的作用和预期的类型。

    【讨论】:

    • 我会写“显式类型”而不是“编译语言”。例如,Haskell 也已编译,但您可以像在 Python 中那样编写隐式声明。
    • 虽然我在这些情况下同意你的观点,但在变量名中强制使用 3 个或更多字符并不意味着它是描述性的。例如,我目前正在使用with open(FILE) as f: items = f.readlines(),其中变量f 非常明显,但我收到了pylint 警告。这让我改成了 flake8。
    • 您还可以更改 pylint 规则以允许 'f' 变量名。 i, j AFAIR 已经有例外。
    • 对于不赞成这个答案的人:我是在 Pylint 中引入规则的人,原因正是给定的。你可能不同意这个决定,但这仍然是问题的答案......
    • 我完全遵循您的推理,但是在算法和数学编程中,某些值通常用一个字母命名。我认为名为@9​​87654326@ 的函数与名为c 的OptionList 完全不同。特别是当我无法将其重命名为 function 时,因为它会影响内置。
    【解决方案4】:

    现在还有一个选项可以覆盖正则表达式。即,如果您想允许单个字符作为变量:

    pylint --variable-rgx="[a-z0-9_]{1,30}$" <filename>
    

    因此,Pylint 将匹配 PEP8,并且不会带来额外的违规行为。也可以添加到.pylintrc

    【讨论】:

    • 对于版本&gt; 1.8.3,这似乎是答案。也可以将其放入您的 .pylintrc 以进行永久配置:variable-rgx=[a-z0-9_]{1,30}$
    • --variable-rgx="[a-z_][a-z0-9_]{0,30}$" 可能更合适一点,"9" 不应该是有效的变量名。
    • pylint 现在有good-names-rgxs,我认为这是一个更好的选择。见stackoverflow.com/questions/21833872/…
    【解决方案5】:

    更深层次的原因是你可能记得你的意图 abcxyz 的意思是当你编写代码时,但当其他人阅读时它,甚至当你回到你的代码时,当你给它一个语义名称时,代码变得更具可读性。我们不会在黑板上写下东西然后擦掉。我们正在编写的代码可能会保留十年或更长时间,并且会被阅读很多次。

    使用语义名称。我使用的语义名称如ratiodenominatorobj_generatorpath 等。输入它们可能需要一两秒钟的时间,但是您可以节省尝试找出什么的时间你从那以后写了半个小时也很值得。

    【讨论】:

    • 谢谢。这是最终代码 -- gist.github.com/amandabee/8969833 -- 我明白你关于我(或你)可以在一年内阅读的代码的观点,但在这种情况下,我认为 x 和 y 是真正的描述性。
    • OTOH 如果我从 XML 文档中提取元素
      ,将其存储在变量“dt”中似乎很清楚,而将其存储为“日期”(这就是这个元素碰巧代表)可能会令人困惑,并且编造诸如“ the_dt_field”之类的东西只是愚蠢的废话。 (不,我无法控制元素的名称;它是其他人的架构。)肯定有很多这样的例外来测试规则。
    • 是的,在 2 年之后,我们仍然会理解 i 是介于 0n 之间的整数,或者 xyz 是3 个浮点数,用于描述 3D 中的一个点。不过,我们可能不理解那些被选择替换它们的复杂变量名。
    【解决方案6】:

    pylint 现在有 good-names-rgxs,它添加了额外的正则表达式模式以允许变量名称。

    不同之处在于variable-rgx 将覆盖任何以前的规则,而good-names-rgxs 在现有规则之上添加规则。这使它更加灵活,因为您不必担心违反以前的规则。

    只需将此行添加到 pylintrc 以允许 1 或 2 个长度变量名称:

    good-names-rgxs=^[_a-z][_a-z0-9]?$
    
    ^          # starts with
    [_a-z]     # 1st character required
    [_a-z0-9]? # 2nd character optional
    $          # ends with
    

    【讨论】:

    • 此外,您可以使用good-names-rgxs 来扩展good-names,而无需重复(从而维护)默认good-names 的列表。
    • 我必须这样做:good-names-rgxs=[_a-z][_a-z0-9]?$
    【解决方案7】:

    pylint 自身生成的配置将允许i, j, k, ex, Run,但不允许x,y,z

    一般的解决方案是为您的帐户 ($HOME/.pylintrc) 或您的项目 (&lt;project&gt;/.pylintrc) 调整您的 .pylintrc

    首先安装pylint,也许在你的.env里面:

    source myenv/bin/activate
    pip install pylint
    

    接下来运行pylint,但文件太长,无法从一开始就手动维护,所以保存在一边:

    pylint --generate-rcfile > ~/.pylintrc--full
    

    查看生成的~/.pylintrc--full。一个街区会​​说:

    [BASIC]
    
    # Good variable names which should always be accepted, separated by a comma.
    good-names=i,
               j,
               k,
               ex,
               Run,
               _
    

    根据需要调整此块(添加x,y,..)以及任何其他块,并将您选择的摘录复制到~/.pylintrc(或&lt;project&gt;/.pylintrc)中。

    【讨论】:

      猜你喜欢
      • 2019-06-06
      • 2015-12-13
      • 1970-01-01
      • 2021-12-09
      • 2018-01-04
      • 2015-03-17
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      相关资源
      最近更新 更多