¿Por qué el uso de len (SECUENCIA) en los valores de condición se considera incorrecto por Pylint?

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 statement 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, francamente lo llama un uso incorrecto .

condición de len-as (C1801) : no use len(SEQUENCE) como valor de condición Se utiliza cuando Pylint detecta un uso incorrecto de len (secuencia) dentro de las condiciones.

Mis bashs de búsqueda tampoco han podido brindarme una explicación más profunda. Entiendo que la propiedad de longitud de una secuencia puede evaluarse perezosamente y que __len__ puede progtwigrse para que tenga efectos secundarios, pero es cuestionable que solo eso sea lo suficientemente problemático para que Pylint considere incorrecto ese 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 está intentando evitar Pylint con el C1801?

¿Cuándo es problemático el uso de len(SEQ) como valor de condición? ¿Qué situaciones principales está intentando evitar Pylint con el C1801?

No es realmente problemático usar len(SEQUENCE) , aunque puede que no sea tan eficiente (vea el comentario de Chepner ). Independientemente, Pylint comprueba el código para el cumplimiento con la guía de estilo PEP 8 que establece que

Para las 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 un progtwigdor ocasional de Python, que navega entre idiomas, consideraría que la construcción de len(SEQUENCE) es más legible y explícita (“Explicit 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 solo 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 utiliza tanto las listas de Python como las matrices NumPy, el mensaje C1801 es menos útil.

Pylint estaba fallando en mi código y la investigación me llevó a este 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) 

Este fue 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 mi corrección de 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 detalles que me faltan, hágamelo saber.