E_n*_*ate 192 python conditional pylint
考虑此代码段:
from os import walk
files = []
for (dirpath, _, filenames) in walk(mydir):
# more code that modifies files
if len(files) == 0: # <-- C1801
return None
Run Code Online (Sandbox Code Playgroud)
Pylint对这条关于if语句行的消息感到震惊:
[pylint] C1801:不要
len(SEQUENCE)用作条件值
乍一看,规则C1801对我来说听起来不太合理,参考指南中的定义并不能解释为什么这是一个问题.事实上,它完全称之为不正确的用法.
len-as-condition(C1801): 不要
len(SEQUENCE)用作条件值当Pylint在条件内检测到len(序列)的错误使用时使用.
我的搜索尝试也未能为我提供更深入的解释.我确实理解序列的长度属性可能会被懒惰地评估,并且__len__可以被编程为具有副作用,但是对于Pylint是否足以使这样的使用不正确而言,这是否有问题是值得怀疑的.因此,在我简单地配置我的项目以忽略规则之前,我想知道我的推理是否缺少某些内容.
什么时候使用len(SEQ)条件值有问题?Pylint试图用C1801避免哪些主要情况?
Ant*_*ica 261
什么时候使用
len(SEQ)条件值有问题?Pylint试图用C1801避免哪些主要情况?
使用它并不是真正的问题len(SEQUENCE)- 虽然它可能效率不高(参见chepner的评论).无论如何,Pylint检查代码是否符合PEP 8样式指南,该指南说明了这一点
对于序列,(字符串,列表,元组),请使用空序列为假的事实.
Run Code Online (Sandbox Code Playgroud)Yes: if not seq: if seq: No: if len(seq): if not len(seq):
作为一个偶然的Python程序员,谁在语言之间徘徊,我认为这个len(SEQUENCE)结构更具可读性和显性性("明确比隐含更好").但是,使用空序列False在布尔上下文中求值的事实被认为更"Pythonic".
小智 38
请注意,在使用NumPy数组时,实际上需要使用len(seq)(而不是仅仅检查seq的bool值).
a = numpy.array(range(10))
if a:
print "a is not empty"
Run Code Online (Sandbox Code Playgroud)
导致异常:ValueError:具有多个元素的数组的真值是不明确的.使用a.any()或a.all()
因此,对于同时使用Python列表和NumPy数组的代码,C1801消息不太有用.
这是 Pylint 中的一个问题,它不再被认为len(x) == 0是不正确的。
您不应该使用裸露 len(x)作为条件。len(x)与显式值(例如if len(x) == 0of)进行比较if len(x) > 0是完全可以的,并且 PEP 8 并未禁止。
来自PEP 8:
Run Code Online (Sandbox Code Playgroud)# Correct: if not seq: if seq: # Wrong: if len(seq): if not len(seq):
请注意,不禁止显式测试长度。Python 之禅指出:
显式的比隐式的好。
if not seq在和之间的选择中if not len(seq),两者都是隐式的,但行为不同。但if len(seq) == 0orif len(seq) > 0是明确的比较,并且在许多情况下是正确的行为。
在 Pylint 中,PR 2815已修复此错误,首次报告为问题 2684。它会继续抱怨if len(seq),但也不会再抱怨if len(seq) > 0。PR 于 2019 年 3 月 19 日合并,因此如果您使用 Pylint 2.4(2019 年 9 月 14 日发布)或更高版本,则不应看到此问题。
在修复https://github.com/PyCQA/pylint/issues/2684和https://github.com/PyCQA/pylint/issues/1405之后,Pylint的下一发行版不再不必要抱怨
感谢PaulRenvoise,PCManticore和adhearn为解决此问题所做的工作!
例如,if len(files) == 0将不再导致pylint抱怨。