Почему 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 скоро будет удален.