76 votes

Pourquoi Pylint n'aime-t-il pas les fonctions intégrées ?

J'ai une ligne comme ça :

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

Pylint affiche un avertissement :

W:  3: Used builtin function 'filter'

Pourquoi ? La compréhension d'une liste est-elle la méthode recommandée ?

Bien sûr, je peux réécrire ça comme ça :

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

Et je ne reçois aucun avertissement, mais je me demandais s'il existait un PEP pour cela ?

1 votes

Curieusement, pylint n'aime pas quand j'utilise la fonction intégrée map mais il n'aime pas non plus lorsque j'importe le fichier map de la fonction cytoolz pour utiliser ceci à la place.

97voto

Ned Batchelder Points 128913

Pylint parle souvent de choses qu'elle ne devrait pas. Vous pouvez désactiver l'avertissement dans un fichier .pylintrc.

Cette page http://pylint-messages.wikidot.com/messages:w0141 indique que le problème est que filter et map ont été remplacés par des compréhensions de listes.

Une ligne comme celle-ci dans votre fichier pylintrc fera taire l'avertissement :

disable=W0141

6 votes

Je ne le savais pas non plus. J'ai lancé pylint avec l'option "-i y" pour inclure le numéro du message, puis j'ai cherché sur Google "pylint W0141", et c'est ce que j'ai trouvé.

1 votes

@NedBatchelder : Merci ! Vous devriez éventuellement aussi ajouter l'en-tête [MESSAGES CONTROL] (voir .pylintrc exemple ) car quelqu'un qui vient de créer ce fichier pourrait ne pas savoir que c'est nécessaire.

3 votes

Pensez à désactiver cette fonction en utilisant un nom de message plus long et plus lisible : # pylint: disable=bad-builtin . Ou dans le pylintrc : [MESSAGES CONTROL] disable=bad-builtin . C'est plus clair qu'un simple numéro d'avertissement.

11voto

user1587329 Points 91

Pourquoi ? La compréhension d'une liste est-elle la méthode recommandée ?

La compréhension de la liste est recommandée dans l'exemple du tutoriel qui stipule

c'est plus concis et plus lisible.

et par la plupart des personnes qui répondent aux questions de l'OS Compréhension de la liste Python Vs. carte donde c'est

  1. plus efficace d'utiliser la compréhension de liste que filter si vous définissez un lambda à chaque fois
  2. peut-être plus lisible (et avec une efficacité similaire) pour utiliser filter si la fonction est prédéfinie
  3. nécessaire d'utiliser filter y map si vous
    • carte map ,
    • curry map ou
    • utiliser la programmation fonctionnelle

TL;DR : utiliser la compréhension de liste dans la plupart des cas

5voto

benjamin Points 1464

J'ai rencontré le même problème et je n'ai pas réussi à comprendre

pourquoi la fonction intégrée `input' est mauvaise. Si vous voulez

pour le désactiver :

pylint --bad-functions=" [map,filter,apply]" VOTRE_FICHIER_À_VÉRIFIER_ICI

Une fois que vous aimez les paramètres :

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

Vérifiez que vos paramètres sont dans le fichier, par exemple :

cat test.rc | grep -i YOUR_SETTING_HERE

Après cela, vous pouvez utiliser ce fichier localement

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

ou même l'utiliser comme votre fichier rcfile par défaut. Pour cela, je vous renvoie à

pylint --long-help

4 votes

Dans python2, input() est mauvais parce qu'il fait eval(raw_input()) . Vous devez toujours utiliser raw_input() . En python3, input() a le comportement souhaité (renvoie toujours str ).

1voto

J'ai le même avertissement sur mon projet. Je modifie le code source pour être compatible avec py2/3, et pylint m'aide beaucoup.

Running pylint --py3k ne montre que les erreurs de compatibilité.

Dans python 2, si vous utilisez filter il renvoie un list :

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

Mais en python 3, filter et d'autres méthodes similaires ( map , range , zip ) renvoie un itérateur, c'est-à-dire des types incompatibles et peut-être des bogues dans votre code.

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

Pour rendre votre code compatible avec python 2/3, j'utilise une antisèche de Site du futur python

Pour éviter cet avertissement, vous pouvez utiliser 4 approches, qui fonctionnent sur python 2 et 3 :

1 - Utiliser une liste de compréhension comme vous l'avez dit.

2 - Utilisation d'un list en accordant que le retour est toujours une liste matérialisée, le résultat est le même sur les deux versions de python.

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

3 - Utilisation lfilter c'est un futur paquet importé. Il retourne toujours une liste, utilise le filtre sur py2, et list(filter(..) sur py3. Ainsi, les deux pythons ont le même comportement et vous obtenez une syntaxe plus propre.

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

4 - Le meilleur ! Utilisez filter toujours dans une boucle, de cette façon, pylint ne donne pas d'avertissement, et il a une belle augmentation des performances sur python 3.

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

Préférez toujours les fonctions qui fonctionnent sur python 3, car python 2 sera bientôt retiré.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X