Чому Pylint не любить вбудовані функції?


74

У мене такий рядок:

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

Пілінт показує попередження:

W:  3: Used builtin function 'filter'

Чому так? чи розуміння списку є рекомендованим методом?

Звичайно, я можу переписати це так:

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

І я не отримую попереджень, але мені було цікаво, чи є для цього ПЕП?


1
Як не дивно, pylint не любить, коли я використовую вбудовану функцію map, але він не любить, коли я імпортую mapфункцію з, cytoolzщоб використовувати це замість цього.
бли

Відповіді:


95

Пілінт часто базікає про те, чого не повинен. Ви можете вимкнути попередження у файлі .pylintrc.

Ця сторінка http://pylint-messages.wikidot.com/messages:w0141 вказує, що проблема полягає в тому, що фільтр і карта були замінені розуміннями списків.

Рядок, подібний до цього у вашому файлі pylintrc, затихає попередження:

disable=W0141

6
Я про це теж не знав. Я запустив пілінт із позначкою "-i y", щоб включити номер повідомлення, потім погуглив "пілінт W0141", і ось що я знайшов.
Ned Batchelder

1
@NedBatchelder: Дякую! Зрештою, слід також додати заголовок [MESSAGES CONTROL](див. Приклад .pylintrc ), тому що хтось, хто просто створює цей файл mgiht, не знає, що це необхідно.
Martin Thoma

3
Розгляньте можливість відключення цього за допомогою довше, більш зручного для читання імені повідомлення: # pylint: disable=bad-builtin. Або в pylintrc: [MESSAGES CONTROL] disable=bad-builtin. Більш зрозуміло, що просто попереджувальний номер.
johntellsall

10

Чому так? чи розуміння списку є рекомендованим методом?

Розуміння списку рекомендується в прикладі навчального посібника , де зазначено

це лаконічніше і читабельніше.

і більшістю відповідачів на SO's Python List Карта, де вона знаходиться

  1. ефективніше використовувати розуміння списку, ніж filterякщо ви визначаєте lambdaкожен раз
  2. можливо, більш читабельним (і з подібною ефективністю) для використання, filterякщо функція визначена заздалегідь
  3. необхідні для використання filterі mapякщо вам
    • карта map,
    • каррі map, або
    • використовувати функціональне програмування

TL; DR: використовуйте розуміння списку в більшості випадків


5

Я зіткнувся з тією ж проблемою і не міг зрозуміти

чому вбудована функція `input 'погана. Я ви маєте намір

щоб вимкнути його:

pylint --bad-functions = "[карта, фільтр, застосування]" 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 ...

або навіть використовувати його як rc-файл за замовчуванням. Для цього я люб’язно вас посилаю

pylint --long-help

4
У python2 input()це зло, бо воно є eval(raw_input()). Ви завжди повинні використовувати raw_input(). У python3 input()має бажану поведінку (завжди повертається str).
mic_e

1

У мене таке ж попередження щодо мого проекту. Я міняю вихідний код, щоб він був сумісним з py2 / 3, і pylint дуже допомагає.

Запуск pylint --py3kпоказує лише помилки щодо сумісності.

У python 2, якщо use filter, він повертає a 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 - Використання a 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 скоро буде скасовано.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.