tuplas - secuencia mutable en python
¿Por qué Pylint considera incorrecto el uso de len(SECUENCIA) en los valores de condición? (4)
¿Cuándo es problemático el uso de
len(SEQ)
como valor de condición? ¿Qué situaciones principales intenta evitar Pylint con C1801?
No es
realmente
problemático usar
len(SEQUENCE)
, aunque puede que no sea tan eficiente (vea
el comentario de chepner
).
Independientemente, Pylint verifica el código para el cumplimiento de 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 pasa de un idioma a otro, 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 "Pitónico".
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 None
Pylint me alarmó con este mensaje con respecto a la línea con la declaración if:
[pylint] C1801: No utilice
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 francamente un uso incorrecto .
len-as-condition (C1801) : no use
len(SEQUENCE)
como valor de condición Se utiliza cuando Pylint detecta el uso incorrecto de len (secuencia) dentro de las condiciones.
Mis intentos de búsqueda tampoco han podido proporcionarme una explicación más profunda.
Entiendo que la propiedad de longitud de una secuencia puede evaluarse perezosamente, y que
__len__
se puede programar para que tenga efectos secundarios, pero es cuestionable si eso solo es lo suficientemente problemático como para que Pylint considere incorrecto dicho uso.
Por lo tanto, antes de simplemente configurar mi proyecto para ignorar la regla, me gustaría saber si me falta algo en mi razonamiento.
¿Cuándo es problemático el uso de
len(SEQ)
como valor de condición?
¿Qué situaciones principales intenta evitar Pylint con C1801?
La próxima versión de Pylint ya no debería quejarse innecesariamente después de corregir https://github.com/PyCQA/pylint/issues/2684 y https://github.com/PyCQA/pylint/issues/1405
¡Gracias a PaulRenvoise , PaulRenvoise y adhearn por su trabajo para solucionar esto!
Por ejemplo,
if len(files) == 0
ya no hará que pylint se queje.
Pylint estaba fallando en mi código y la investigación me llevó a esta publicación:
../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)
Este era mi código antes:
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)))
Esto fue después de la reparación de mi código.
Al usar el
attribute
int()
, parece que he satisfecho el Pep8 / Pylint y no parece tener un impacto negativo en mi código:
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)))
Mi arreglo
Al agregar
.__trunc__()
a la secuencia parece haber resuelto la necesidad.
No veo una diferencia en el comportamiento, pero si alguien sabe los detalles que me faltan, hágamelo saber.
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. Utilice a.any () o a.all ()
Y, por lo tanto, para el código que usa listas Python y matrices NumPy, el mensaje C1801 no es útil.