Betrachtet man diesen Codeausschnitt:
from os import walk
files = []
for (dirpath, _, filenames) in walk(mydir):
# more code that modifies files
if len(files) == 0: # <-- C1801
return None
Ich wurde von Pylint mit dieser Nachricht bezüglich der Zeile mit der if-Anweisung alarmiert:
[Pylint] C1801: Verwenden Sie nicht
len(SEQUENCE)
als Bedingungswert
Die Regel C1801 klang für mich auf den ersten Blick nicht sehr vernünftig, und die Definition im Referenzhandbuch erklärt nicht, warum dies ein Problem ist. Tatsächlich nennt es geradezu eine falsche Verwendung .
len-as-condition (C1801) :
len(SEQUENCE)
nicht als Bedingungswert verwenden Wird verwendet, wenn Pylint eine falsche Erkennung vornimmt Verwendung von len (Sequenz) innerhalb von Bedingungen.
Meine Suchversuche haben mir auch keine tiefere Erklärung geliefert. Ich verstehe, dass die Längeneigenschaft einer Sequenz möglicherweise träge ausgewertet wird und dass __len__
auf Nebenwirkungen programmiert werden kann, aber es ist fraglich, ob dies allein für Pylint problematisch genug ist, eine solche Verwendung als falsch zu bezeichnen. Bevor ich mein Projekt einfach so konfiguriere, dass es die Regel ignoriert, möchte ich wissen, ob ich etwas in meiner Argumentation vermisse.
Wann ist die Verwendung von len(SEQ)
als Bedingungswert problematisch? Welche wichtigen Situationen versucht Pylint mit C1801 zu vermeiden?
Wann ist die Verwendung von
len(SEQ)
als Bedingungswert problematisch? Welche wichtigen Situationen versucht Pylint mit C1801 zu vermeiden?
Es ist nicht wirklich problematisch, len(SEQUENCE)
zu verwenden - obwohl es möglicherweise nicht so effizient ist (siehe Kommentar von chepner ). Unabhängig davon überprüft Pylint den Code auf Übereinstimmung mit dem PEP 8 Style Guide , in dem dies angegeben ist
Verwenden Sie für Sequenzen (Strings, Listen, Tupel) die Tatsache, dass leere Sequenzen falsch sind.
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
Als gelegentlicher Python Programmierer, der zwischen Sprachen wechselt, würde ich das len(SEQUENCE)
-Konstrukt als lesbarer und expliziter betrachten ("Explizit ist besser als implizit"). Die Verwendung der Tatsache, dass eine leere Sequenz in einem Booleschen Kontext zu False
ausgewertet wird, wird jedoch als „pythonischer“ angesehen.
Beachten Sie, dass bei der Verwendung von NumPy-Arrays die Verwendung von len (seq) erforderlich ist (anstatt nur den bool-Wert von seq zu überprüfen).
a = numpy.array(range(10))
if a:
print "a is not empty"
führt zu einer Ausnahme: ValueError: Der Wahrheitswert eines Arrays mit mehr als einem Element ist nicht eindeutig. Benutze a.any () oder a.all ()
Daher ist die C1801-Nachricht für Code, der sowohl Python -Listen als auch NumPy-Arrays verwendet, weniger hilfreich.
Die nächste Version von Pylint sollte sich nicht mehr unnötig beschweren, nachdem https://github.com/PyCQA/pylint/issues/2684 und https://github.com/PyCQA/pylint/ Ausgaben/1405
Vielen Dank an PaulRenvoise , PCManticore und adhearn für ihre Arbeit an der Behebung dieses Problems!
Zum Beispiel führt if len(files) == 0
nicht mehr dazu, dass sich Pylint beschwert.
Pylint scheiterte an meinem Code. Nachforschungen führten mich zu diesem Beitrag:
../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)
Dies war mein Code vor:
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)))
Das war nach meinem Code-Fix. Durch die Verwendung von int()
attribute
habe ich anscheinend den Pep8/Pylint erfüllt und scheint meinen Code nicht negativ zu beeinflussen:
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)))
Durch Hinzufügen von .__trunc__()
zu der Sequenz scheint das Bedürfnis geklärt zu sein.
Ich sehe keinen Unterschied im Verhalten, aber wenn jemand Einzelheiten weiß, die mir fehlen, lassen Sie es mich bitte wissen.