Teniendo en cuenta este fragmento de código:
from os import walk files = [] for (dirpath, _, filenames) in walk(mydir): # More code that modifies files if len(files) == 0: # <-- C1801 return NonePylint me alarmó con este mensaje con respecto a la línea con la declaración if:
[pylint] C1801: No usar
len(SEQUENCE)como valor de condición
La regla C1801, a primera vista, no me pareció muy razonable y la definición en la guía de referencia no explica por qué esto es un problema. De hecho, lo llama llanamente un uso incorrecto .
len-as-condition (C1801) : no use
len(SEQUENCE)como valor de condición. Se usa cuando Pylint detecta un uso incorrecto de len (secuencia) dentro de las condiciones.
Mis intentos de búsqueda tampoco han logrado proporcionarme una explicación más profunda. Entiendo que la propiedad de longitud de una secuencia puede evaluarse con pereza, y que __len__ puede programarse para tener efectos secundarios, pero es cuestionable si eso solo es lo suficientemente problemático como para que Pylint califique tal uso como incorrecto. Por lo tanto, antes de simplemente configurar mi proyecto para ignorar la regla, me gustaría saber si me estoy perdiendo algo en mi razonamiento.
¿Cuándo es problemático el uso de len(SEQ) como valor de condición? ¿Qué situaciones importantes intenta evitar Pylint con C1801?
¿Cuándo es problemático el uso de
len(SEQ)como valor de condición? ¿Qué situaciones importantes intenta evitar Pylint con C1801?
No es realmente problemático usar len(SEQUENCE) , aunque puede que no sea tan eficiente (ver el comentario de Chepner ). Independientemente, Pylint verifica el código para cumplir con la guía de estilo PEP 8 que establece que
Para secuencias (cadenas, listas, tuplas), use el hecho de que las secuencias vacías son falsas.
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
Como programador ocasional de Python, que revolotea entre lenguajes, consideraría que la construcción len(SEQUENCE) es más legible y explícita ("Explícito es mejor que implícito"). Sin embargo, usar el hecho de que una secuencia vacía se evalúa como False en un contexto booleano se considera más "Pythonic".
Tenga en cuenta que, de hecho, se requiere el uso de len (seq) (en lugar de simplemente verificar el valor bool de seq) cuando se usan matrices NumPy.
a = numpy.array(range(10)) if a: print "a is not empty"da como resultado una excepción: ValueError: el valor de verdad de una matriz con más de un elemento es ambiguo. Use a.any() o a.all()
Y, por lo tanto, para el código que usa listas de Python y matrices NumPy, el mensaje C1801 es menos que útil.
Este fue un problema en Pylint, y ya no considera len(x) == 0 como incorrecto.
No debe usar un len(x) desnudo como condición. Comparar len(x) con un valor explícito, como if len(x) == 0 if len(x) > 0 está totalmente bien y no está prohibido por PEP 8.
Desde PEP 8 :
# Correct: if not seq: if seq: # Wrong: if len(seq): if not len(seq):
Tenga en cuenta que no está prohibido probar explícitamente la longitud . El Zen de Python afirma:
Explícito es mejor que implícito.
En la elección entre if not seq y if not len(seq) , ambos están implícitos, pero el comportamiento es diferente. Pero if len(seq) == 0 o if len(seq) > 0 son comparaciones explícitas y en muchos contextos son el comportamiento correcto.
En Pylint, PR 2815 solucionó este error, informado por primera vez como problema 2684 . Continuará quejándose de if len(seq) , pero ya no se quejará de if len(seq) > 0 . El PR se fusionó el 19 de marzo de 2019, por lo que si está utilizando Pylint 2.4 (lanzado el 14 de septiembre de 2019), no debería ver este problema.