Warum mag Pylint keine eingebauten Funktionen?

74

Ich habe eine Zeile wie diese:

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

Pylint zeigt eine Warnung:

W:  3: Used builtin function 'filter'

Warum das? Ist ein Listenverständnis die empfohlene Methode?

Natürlich kann ich das so umschreiben:

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

Und ich bekomme keine Warnungen, aber ich habe mich gefragt, ob es dafür einen PEP gibt?

igorgue
quelle
1
Lustigerweise mag Pylint nicht, wenn ich die eingebaute Funktion verwende map, aber es gefällt auch nicht, wenn ich die mapFunktion importiere cytoolz, um diese stattdessen zu verwenden.
bli

Antworten:

95

Pylint plaudert oft über Dinge, die es nicht sollte. Sie können die Warnung in einer .pylintrc-Datei deaktivieren.

Diese Seite http://pylint-messages.wikidot.com/messages:w0141 weist darauf hin, dass das Problem darin besteht, dass Filter und Karte durch Listenverständnisse ersetzt wurden.

Eine Zeile wie diese in Ihrer pylintrc-Datei löscht die Warnung:

disable=W0141
Ned Batchelder
quelle
6
Ich wusste es auch nicht. Ich habe pylint mit dem Flag "-i y" ausgeführt, um die Nachrichtennummer einzuschließen, dann habe ich "pylint W0141" gegoogelt, und das habe ich gefunden.
Ned Batchelder
1
@NedBatchelder: Danke! Sie sollten eventuell auch den Header hinzufügen [MESSAGES CONTROL](siehe Beispiel .pylintrc ), da jemand, der gerade diese Datei erstellt, möglicherweise nicht weiß, dass dies erforderlich ist.
Martin Thoma
3
Deaktivieren Sie dies, indem Sie den längeren, besser lesbaren Nachrichtennamen verwenden : # pylint: disable=bad-builtin. Oder in der Pylintrc : [MESSAGES CONTROL] disable=bad-builtin. Es ist klarer, dass nur eine Warnnummer.
johntellsall
10

Warum das? Ist ein Listenverständnis die empfohlene Methode?

Das Listenverständnis wird im Tutorial-Beispiel empfohlen, in dem angegeben ist

es ist prägnanter und lesbarer.

und von den meisten Antwortenden auf SOs Python List Comprehension Vs. Karte wo es ist

  1. Das Listenverständnis ist effizienter , als filterwenn Sie lambdajedes Mal eine definieren
  2. Möglicherweise besser lesbar (und mit ähnlicher Effizienz), filterwenn die Funktion vordefiniert ist
  3. notwendig zu verwenden filterund mapwenn Sie
    • Karte map,
    • Curry mapoder
    • Verwenden Sie die funktionale Programmierung

TL; DR: Verwenden Sie in den meisten Fällen das Listenverständnis

serv-inc
quelle
5

Ich stieß auf das gleiche Problem und konnte es nicht herausfinden

warum die eingebaute Funktion "Eingabe" schlecht ist. Ich, du hast vor

um es zu deaktivieren:

pylint --bad-functions = "[zuordnen, filtern, anwenden]" YOUR_FILE_TO_CHECK_HERE

Sobald Ihnen die Einstellungen gefallen:

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

Stellen Sie sicher, dass sich Ihre Einstellungen in der Datei befinden, z.

cat test.rc | grep -i YOUR_SETTING_HERE

Danach können Sie diese Datei lokal verwenden

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

oder verwenden Sie es sogar als Standard-RC-Datei. Dafür verweise ich Sie freundlich

pylint --long-help
Benjamin
quelle
4
In Python2 input()ist böse, weil es tut eval(raw_input()). Sie sollten immer verwenden raw_input(). Hat in Python3 input()das gewünschte Verhalten (kehrt immer zurück str).
mic_e
1

Ich habe die gleiche Warnung auf meinem Projekt. Ich ändere den Quellcode so, dass er py2 / 3-kompatibel ist, und pylint hilft sehr.

Beim Ausführen pylint --py3kwerden nur Kompatibilitätsfehler angezeigt.

In Python 2 wird bei Verwendung filterFolgendes zurückgegeben list:

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

Aber in Python 3, filterund anderen ähnlichen Verfahren ( map, range, zip, ..) gibt einen Iterator, die inkompatible Typen und vielleicht Ursache Fehler in Ihrem Code.

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

Um Ihren Code Python 2/3 kompatibel zu machen, verwende ich einen Spickzettel von der zukünftigen Python-Site

Um diese Warnung zu vermeiden, können Sie 4 Ansätze verwenden, die für Python 2 und 3 funktionieren:

1 - Verwenden Sie ein Listenverständnis, wie Sie gesagt haben.

2 - Gewähren Sie mithilfe einer listFunktion, dass return immer eine materialisierte Liste ist. Das Ergebnis ist in beiden Python-Versionen gleich

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

3 - Mit lfilter, das ist ein zukünftiger Paketimport. Es gibt immer eine Liste zurück, verwendet Filter für py2 und list(filter(..)für py3. Beide Pythons haben also das gleiche Verhalten und Sie haben eine sauberere Syntax.

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

4 - Das Beste! Verwenden Sie filterimmer in einer Schleife, auf diese Weise gibt Pylint keine Warnungen aus und hat eine schöne Leistungssteigerung auf Python 3.

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

Bevorzugen Sie immer Funktionen, die unter Python 3 funktionieren, da Python 2 bald eingestellt wird.

Jorge Continuous
quelle