为什么在 Pylint 认为不正确的条件值中使用 len(SEQUENCE)?
Why is the use of len(SEQUENCE) in condition values considered incorrect by Pylint?
考虑这个代码片段:
from os import walk
files = []
for (dirpath, _, filenames) in walk(mydir):
# More code that modifies files
if len(files) == 0: # <-- C1801
return None
Pylint 关于带有 if 语句的行的这条消息让我感到震惊:
[pylint] C1801:Do not use len(SEQUENCE)
as condition value
C1801 规则,乍一看,我觉得不太合理,definition on the reference guide 也没有解释为什么这是个问题。事实上,它完全称其为错误使用。
len-as-condition (C1801):
Do not use len(SEQUENCE)
as condition value Used when Pylint detects incorrect use of len(sequence) inside conditions.
我的搜索尝试也未能为我提供更深入的解释。我确实理解序列的长度 属性 可能会被懒惰地评估,并且 __len__
可以被编程为有副作用,但值得怀疑的是,仅凭这一点是否足以让 Pylint 称这种使用不正确.因此,在我简单地配置我的项目以忽略该规则之前,我想知道我的推理是否遗漏了什么。
什么时候使用 len(SEQ)
作为条件值有问题? Pylint 试图通过 C1801 避免哪些主要情况?
When is the use of len(SEQ)
as a condition value problematic? What major
situations is Pylint attempting to avoid with C1801?
使用 len(SEQUENCE)
确实 没有问题——尽管它可能效率不高(参见 ). Regardless, Pylint checks code for compliance with the PEP 8 style guide 指出
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
<b>Yes:</b> if not seq:
if seq:
<b>No:</b> if len(seq):
if not len(seq):
作为偶尔在不同语言之间穿梭的 Python 程序员,我认为 len(SEQUENCE)
结构更具可读性和明确性(“明确优于隐含”)。但是,使用空序列在布尔上下文中计算为 False
这一事实被认为更“Pythonic”。
请注意,在使用 NumPy 数组时,实际上需要使用 len(seq)(而不是仅仅检查 seq 的 bool 值)。
a = numpy.array(range(10))
if a:
print "a is not empty"
导致异常:
ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
因此,对于同时使用 Python 列表和 NumPy 数组的代码,C1801 消息的帮助不大。
Pylint 因我的代码而失败,研究使我想到了这个 post:
../filename.py:49:11: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)
../filename.py:49:34: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)
这是我之前的代码:
def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
if len(dirnames) == 0 and len(filenames) == 0:
print("Exists: {} : Absolute Path: {}".format(
os.path.exists(fullpath), os.path.abspath(fullpath)))
这是在我的代码修复之后。通过使用 int()
attribute
,我似乎已经满足 Pep8/Pylint 并且似乎没有对我的代码产生负面影响:
def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
if len(dirnames).__trunc__() == 0 and len(filenames).__trunc__() == 0:
print("Exists: {} : Absolute Path: {}".format(
os.path.exists(fullpath), os.path.abspath(fullpath)))
我的修复
通过在序列中添加 .__trunc__()
似乎已经满足了需求。
我看不出行为有什么不同,但如果有人知道我遗漏的细节,请告诉我。
这是 Pylint 中的一个问题,它不再认为 len(x) == 0
不正确。
您不应使用 bare len(x)
作为条件。将 len(x)
与显式值进行比较,例如 if len(x) > 0
的 if len(x) == 0
是完全可以的,并且 PEP 8 不禁止。
来自 PEP 8:
# Correct:
if not seq:
if seq:
# Wrong:
if len(seq):
if not len(seq):
请注意,不禁止显式测试长度。 Zen of Python 状态:
Explicit is better than implicit.
在if not seq
和if not len(seq)
之间的选择中,两者都是隐含的,但行为不同。但是 if len(seq) == 0
或 if len(seq) > 0
是明确的比较,在许多情况下都是正确的行为。
在 Pylint 中,PR 2815 has fixed this bug, first reported as issue 2684。它会继续抱怨if len(seq)
,但不会再抱怨if len(seq) > 0
。 PR 于 2019-03-19 合并,因此如果您使用的是 Pylint 2.4(2019-09-14 发布),您应该不会看到此问题。
考虑这个代码片段:
from os import walk
files = []
for (dirpath, _, filenames) in walk(mydir):
# More code that modifies files
if len(files) == 0: # <-- C1801
return None
Pylint 关于带有 if 语句的行的这条消息让我感到震惊:
[pylint] C1801:Do not use
len(SEQUENCE)
as condition value
C1801 规则,乍一看,我觉得不太合理,definition on the reference guide 也没有解释为什么这是个问题。事实上,它完全称其为错误使用。
len-as-condition (C1801): Do not use
len(SEQUENCE)
as condition value Used when Pylint detects incorrect use of len(sequence) inside conditions.
我的搜索尝试也未能为我提供更深入的解释。我确实理解序列的长度 属性 可能会被懒惰地评估,并且 __len__
可以被编程为有副作用,但值得怀疑的是,仅凭这一点是否足以让 Pylint 称这种使用不正确.因此,在我简单地配置我的项目以忽略该规则之前,我想知道我的推理是否遗漏了什么。
什么时候使用 len(SEQ)
作为条件值有问题? Pylint 试图通过 C1801 避免哪些主要情况?
When is the use of
len(SEQ)
as a condition value problematic? What major situations is Pylint attempting to avoid with C1801?
使用 len(SEQUENCE)
确实 没有问题——尽管它可能效率不高(参见
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
<b>Yes:</b> if not seq: if seq: <b>No:</b> if len(seq): if not len(seq):
作为偶尔在不同语言之间穿梭的 Python 程序员,我认为 len(SEQUENCE)
结构更具可读性和明确性(“明确优于隐含”)。但是,使用空序列在布尔上下文中计算为 False
这一事实被认为更“Pythonic”。
请注意,在使用 NumPy 数组时,实际上需要使用 len(seq)(而不是仅仅检查 seq 的 bool 值)。
a = numpy.array(range(10))
if a:
print "a is not empty"
导致异常: ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
因此,对于同时使用 Python 列表和 NumPy 数组的代码,C1801 消息的帮助不大。
Pylint 因我的代码而失败,研究使我想到了这个 post:
../filename.py:49:11: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)
../filename.py:49:34: C1801: Do not use `len(SEQUENCE)` to determine if a sequence is empty (len-as-condition)
这是我之前的代码:
def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
if len(dirnames) == 0 and len(filenames) == 0:
print("Exists: {} : Absolute Path: {}".format(
os.path.exists(fullpath), os.path.abspath(fullpath)))
这是在我的代码修复之后。通过使用 int()
attribute
,我似乎已经满足 Pep8/Pylint 并且似乎没有对我的代码产生负面影响:
def list_empty_folders(directory):
"""The Module Has Been Build to list empty Mac Folders."""
for (fullpath, dirnames, filenames) in os.walk(directory):
if len(dirnames).__trunc__() == 0 and len(filenames).__trunc__() == 0:
print("Exists: {} : Absolute Path: {}".format(
os.path.exists(fullpath), os.path.abspath(fullpath)))
我的修复
通过在序列中添加 .__trunc__()
似乎已经满足了需求。
我看不出行为有什么不同,但如果有人知道我遗漏的细节,请告诉我。
这是 Pylint 中的一个问题,它不再认为 len(x) == 0
不正确。
您不应使用 bare len(x)
作为条件。将 len(x)
与显式值进行比较,例如 if len(x) > 0
的 if len(x) == 0
是完全可以的,并且 PEP 8 不禁止。
来自 PEP 8:
# Correct: if not seq: if seq: # Wrong: if len(seq): if not len(seq):
请注意,不禁止显式测试长度。 Zen of Python 状态:
Explicit is better than implicit.
在if not seq
和if not len(seq)
之间的选择中,两者都是隐含的,但行为不同。但是 if len(seq) == 0
或 if len(seq) > 0
是明确的比较,在许多情况下都是正确的行为。
在 Pylint 中,PR 2815 has fixed this bug, first reported as issue 2684。它会继续抱怨if len(seq)
,但不会再抱怨if len(seq) > 0
。 PR 于 2019-03-19 合并,因此如果您使用的是 Pylint 2.4(2019-09-14 发布),您应该不会看到此问题。