Considérant cet extrait de code:
from os import walk
files = []
for (dirpath, _, filenames) in walk(mydir):
# more code that modifies files
if len(files) == 0: # <-- C1801
return None
Pylint m'a alarmé avec ce message concernant la ligne avec la déclaration if:
[pylint] C1801: n'utilisez pas
len(SEQUENCE)
comme valeur de condition
La règle C1801, à première vue, ne me paraissait pas très raisonnable, et le définition sur le guide de référence n'explique pas pourquoi il s'agit d'un problème. En fait, il l'appelle carrément un usage incorrect .
len-as-condition (C1801) : Ne pas utiliser
len(SEQUENCE)
comme valeur de condition Utilisé lorsque Pylint détecte une erreur utilisation de len (séquence) à l'intérieur des conditions.
Mes tentatives de recherche ont également échoué à me fournir une explication plus profonde. Je comprends que la propriété de longueur d’une séquence puisse être évaluée paresseusement et que __len__
puisse être programmé pour avoir des effets secondaires, mais on peut se demander si cela est suffisamment problématique pour que Pylint appelle une telle utilisation incorrecte. Par conséquent, avant de configurer simplement mon projet pour ignorer la règle, j'aimerais savoir si quelque chose me manque dans mon raisonnement.
Quand l'utilisation de len(SEQ)
en tant que valeur de condition pose-t-elle problème? Quelles sont les principales situations que Pylint tente d'éviter avec le C1801?
Quand l'utilisation de
len(SEQ)
en tant que valeur de condition pose-t-elle problème? Quelles sont les principales situations que Pylint tente d'éviter avec C1801?
Il n’est pas vraiment problématique d’utiliser len(SEQUENCE)
- bien que cela puisse ne pas être aussi efficace (voir commentaire de chepner ). Quoi qu’il en soit, Pylint vérifie la conformité du code avec le guide de style PEP 8 qui stipule que
Pour les séquences (chaînes, listes, tuples), utilisez le fait que les séquences vides sont fausses.
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
En tant que programmeur Python occasionnel, qui navigue entre les langages, je considérerais que la construction len(SEQUENCE)
est plus lisible et explicite ("Explicit vaut mieux qu'implicite"). Cependant, l'utilisation du fait qu'une séquence vide est évaluée à False
dans un contexte booléen est considérée comme plus "Pythonique".
Notez que l'utilisation de len (seq) est en fait requise (au lieu de simplement vérifier la valeur booléenne de seq) lors de l'utilisation de tableaux NumPy.
a = numpy.array(range(10))
if a:
print "a is not empty"
génère une exception: ValueError: la valeur de vérité d'un tableau comportant plusieurs éléments est ambiguë. Utilisez a.any () ou a.all ()
Et par conséquent, pour le code qui utilise à la fois les listes Python et les tableaux NumPy, le message C1801 n’est pas utile.
La prochaine version de Pylint ne devrait plus se plaindre après la correction (https://github.com/PyCQA/pylint/issues/2684 et https://github.com/PyCQA/pylint/ issues/1405
Merci à PaulRenvoise , PCManticore et adhearn pour le travail qu’ils ont accompli pour résoudre ce problème!
Par exemple, if len(files) == 0
ne fera plus se plaindre pylint.
Pylint échouait pour mon code et les recherches m'ont conduit à ce poste:
../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)
C'était mon code avant:
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)))
C'était après la correction de mon code. En utilisant la int()
attribute
, il semble que je sois satisfait de Pep8/Pylint et que cela ne semble pas avoir d'impact négatif sur mon code:
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)))
En ajoutant .__trunc__()
à la séquence, le besoin semble avoir été réglé.
Je ne vois pas de différence dans le comportement, mais si quelqu'un sait les détails qui me manquent, faites-le moi savoir.