Подтвердить что ты не робот

Почему использование len (SEQUENCE) в значениях условий считается неправильным Pylint?

Учитывая этот фрагмент кода:

from os import walk

files = []
for (dirpath, _, filenames) in walk(mydir):
    # more code that modifies files
if len(files) == 0: # <-- C1801
    return None

Я был встревожен Пилинтом с этим сообщением относительно строки с выражением if:

[pylint] C1801: Не используйте len(SEQUENCE) как значение условия

Правило C1801, на первый взгляд, показалось мне не очень разумным, а определение в справочном руководстве не объясняет, почему это это проблема. Фактически, он прямо называет его неправильным использованием.

len-as-condition (C1801):   Не используйте len(SEQUENCE) в качестве значения условия Используется, когда Pylint обнаруживает неправильное использование len (последовательности) внутри условий.

Мои попытки поиска также не дали мне более глубокого объяснения. Я понимаю, что свойство длины последовательности можно лениво оценить и что __len__ можно запрограммировать на наличие побочных эффектов, но сомнительно, достаточно ли это достаточно для того, чтобы Пилинт назвал такое использование неправильным. Следовательно, прежде чем я просто сконфигурирую свой проект на игнорирование правила, я хотел бы знать, не хватает ли я чего-то в своих рассуждениях.

Когда использование len(SEQ) в качестве значения условия проблематично? Какие основные ситуации Pylint пытается избежать с помощью C1801?

4b9b3361

Ответ 1

Когда использование len(SEQ) в качестве значения условия проблематично? Какие основные ситуации Pylint пытается избежать с C1801?

Не очень проблематично использовать len(SEQUENCE) - хотя это может быть не так эффективно (см. комментарий для чатов). Несмотря на это, Pylint проверяет код на соответствие руководству по стилю PEP 8, в котором говорится, что

Для последовательностей (строки, списки, кортежи) используйте тот факт, что пустые последовательности являются ложными.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):

Как случайный программист на языке Python, который перемещается между языками, Id рассматривает конструкцию len(SEQUENCE) как более читаемую и явную ( "Явный лучше, чем неявный" ). Однако использование того факта, что пустая последовательность оценивается как False в булевом контексте, считается более "Pythonic".

Ответ 2

Обратите внимание, что использование len (seq) на самом деле требуется (вместо проверки значения bool seq) при использовании массивов NumPy.

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

приводит к исключению: ValueError: Значение истины массива с более чем одним элементом неоднозначно. Используйте a.any() или a.all()

И, следовательно, для кода, который использует как списки Python, так и массивы NumPy, сообщение C1801 менее полезно.

Ответ 3

Pylint терпел неудачу для моего кода, и исследование привело меня к этому сообщению:

../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)

Это был мой код раньше:

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)))

Это было после исправления моего кода. Используя attribute int(), я, кажется, удовлетворил Pep8/Pylint и, похоже, не оказывает негативного влияния на мой код:

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)))

Мое исправление

Добавив .__trunc__() к последовательности, она, похоже, исчерпала необходимость.

Я не вижу различий в поведении, но если кто-то знает особенности, которые мне не хватает, пожалуйста, дайте мне знать.