Почему Pylint не поддерживает встроенные функции?

У меня есть строка вроде этого:

filter(lambda x: x == 1, [1, 1, 2])

Pylint показывает предупреждение:

W:  3: Used builtin function 'filter'

Почему? является ли понимание списка рекомендуемым методом?

Конечно, я могу переписать это следующим образом:

[x for x in [1, 1, 2] if x == 1]

И я не получаю никаких предупреждений, но мне было интересно, есть ли для этого PEP?

Ответ 1

Пилинт часто болтает о вещах, которых это не должно. Вы можете отключить предупреждение в файле .pylintrc.

Эта страница http://pylint-messages.wikidot.com/messages:w0141 указывает, что проблема заключается в том, что фильтр и карта были заменены на понимание списков.

Строка, подобная этой в вашем файле pylintrc, закроет предупреждение:

disable=W0141

Ответ 2

Почему? является ли понимание списка рекомендуемым методом?

В

его более сжатый и читаемый.

и большинством ответчиков на SO , где

более эффективно использовать понимание списка, чем filter, если вы каждый раз определяете lambda может быть более читаемым (и с аналогичной эффективностью) использовать filter, если функция предварительно определена необходимо использовать filter и map, если вы map map, curry map, или использовать функциональное программирование

TL; DR: использование списка в большинстве случаев

Ответ 3

Я столкнулся с той же проблемой и не мог понять

почему встроенная функция `input 'плоха. Я намерен

чтобы отключить его:

pylint --bad-functions = "[map, filter, apply]" YOUR_FILE_TO_CHECK_HERE

Как только вам понравятся настройки:

pylint --bad-functions="[map,filter,apply]" --some-other-supercool-settings-of-yours
--generate-rcfile > test.rc

Убедитесь, что ваши настройки находятся в файле, например:

cat test.rc | grep -i YOUR_SETTING_HERE

После этого вы можете использовать этот файл локально

pylint --rcfile test.rc --your-other-command-line-args ...

или даже использовать его как ваш rcfile по умолчанию. Для этого я любезно ссылаюсь на

pylint --long-help

Ответ 4

У меня такое же предупреждение о моем проекте. Я изменяю исходный код на py2/3-совместимый, и Pylint очень помогает.

Запуск pylint --py3k показывает только ошибки о совместимости.

В Python 2, если использовать filter, он возвращает list:

>>> my_list = filter(lambda x: x == 1, [1, 1, 2])
>>> my_list
[1, 1]
>>> type(my_list)
<type 'list'>

Но в python 3, filter и другие подобные методы (map, range, zip,..) возвращают итератор, который является несовместимым типом и, возможно, вызывает ошибки в вашем коде.

>>> my_list = filter(lambda x: x == 1, [1, 1, 2])
>>> my_list
<filter object at 0x10853ac50>
>>> type(my_list)
<class 'filter'>

Чтобы сделать ваш код Python 2/3 совместимым, я использую шпаргалку с будущего сайта Python

Чтобы избежать этого предупреждения, вы можете использовать 4 подхода, которые работают на Python 2 и 3:

1 - Использование понимания списка, как вы сказали.

2 - Используя функцию list, предоставьте, что return всегда является материализованным списком, результат одинаков для обеих версий Python

>>> list(filter(lambda x: x == 1, [1, 1, 2]))
[1, 1]

3 - Использование lfilter, чтобы импортировать будущий пакет. Он всегда возвращает список, использует фильтр на py2 и list(filter(..) на py3. Таким образом, оба питона имеют одинаковое поведение, и вы получаете более чистый синтаксис.

>>> from future.utils import lfilter
>>> lfilter(lambda x: x == 1, [1, 1, 2])
[1, 1]

4 - лучшее! Используйте filter всегда в цикле, таким образом, Pylint не дает предупреждений, и это имеет хороший прирост производительности на Python 3.

>>> for number in filter(lambda x: x == 1, [1, 1, 2]):
>>>     print(number)
>>> 1
>>> 1

Всегда предпочитайте функции, которые работают на Python 3, потому что Python 2 скоро будет удален.