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


Considerando 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

Me alarmó Pylint 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 de en la guía de referencia no explica por qué esto es un problema. De hecho, lo llama francamente un uso incorrecto.

Len-como condición (C1801) : No utilice len(SEQUENCE) como valor de condición Utilizado cuando Pylint detecta el uso incorrecto de len(secuencia) dentro de las condiciones.

Mis intentos de búsqueda tampoco me han proporcionado una explicación más profunda. Entiendo que la propiedad de longitud de una secuencia puede evaluarse perezosamente, y que __len__ puede programarse para tener efectos secundarios, pero es cuestionable si eso por sí solo es lo suficientemente problemático como para que Pylint llame incorrecto tal uso. Por lo tanto, antes de que 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 importantes intenta evitar Pylint con C1801?

Author: E_net4, 2017-03-30

2 answers

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

No es realmente problemático usar len(SEQUENCE) – aunque puede no ser tan eficiente (ver comentario de chepner). En cualquier caso, Pylint comprueba el cumplimiento del código 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 falso.

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 ("Lo explícito es mejor que lo implícito"). Sin embargo, usar el hecho de que una secuencia vacía evalúa False en un contexto booleano se considera más "pitónico".

 159
Author: Anthony Geoghegan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-18 15:49:48

Tenga en cuenta que el uso de len(seq) es de hecho necesario (en lugar de simplemente comprobar el valor bool de seq) cuando se utilizan arrays NumPy.

a = numpy.array(range(10))
if a:
    print "a is not empty"

Resulta en una excepción: ValueError: El valor de verdad de un array con más de un elemento es ambiguo. Use a.any() o a. all()

Y por lo tanto para el código que usa tanto listas de Python como arrays NumPy, el mensaje C1801 no es muy útil.

 24
Author: Cameron Hayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-08 20:46:20