Soll ich wirklich alle Großbuchstaben für meine Konstanten verwenden?

34

Ich bin ein Python-Programmierer, der in erster Linie Pylint zum Löschen von Quellcode verwendet. Ich kann alle Warnungen bis auf eine beseitigen: Ungültiger Name für eine Konstante. Das Ändern des Namens in Großbuchstaben behebt das Problem, aber soll ich das wirklich tun? Wenn ich das mache, finde ich, dass mein Code hässlich aussieht, da die meisten Variablen konstant sind (laut Pylint).

Abhishek Kumar
quelle
1
Wenn die meisten Variablen Konstanten auf Modulebene sind, tun Sie wahrscheinlich etwas Ungewöhnliches. Die meisten von ihnen sollten in Funktionen leben.
RemcoGerlich
1
Können Sie uns ein Beispiel Ihres Codes zeigen, den Pylint für Konstanten hält?
Winston Ewert
@ WinstonEwertNOTES_DIRECTORY = argv[1] chdir(NOTES_DIRECTORY) FILES = glob('*.txt') RAND_FILE = choice(FILES) with open(RAND_FILE) as notes_file: POINTS = notes_file.readlines() RAND_POINT = choice(POINTS)
Abhishek Kumar
@AbhishekKumar, ist Ihr Code in einer Funktion oder auf der obersten Ebene?
Winston Ewert
@ WinstonEwert Auf der obersten Ebene und nachdem Sie die Anweisungen von PyLint befolgt haben.
Abhishek Kumar

Antworten:

33

Sie schreiben wahrscheinlich folgenden Code:

notes_director = argv[1]
chdir(notes_director)
files = glob('*.txt')
rand_file = choice(files)
with open(rand_file) as notes_file: 
    points = notes_file.readlines() 
    rand_point = choice(points)

Sie sollten diesen Code in eine Funktion verschieben:

def main():
    notes_director = argv[1]
    chdir(notes_director)
    files = glob('*.txt')
    rand_file = choice(files)
    with open(rand_file) as notes_file: 
        points = notes_file.readlines() 
        rand_point = choice(points)

# actually call the main function    
main()

Pylint geht davon aus, dass sich der Code, der die Arbeit tatsächlich erledigt, in einer Funktion befindet. Da Sie diesen Code auf der obersten Ebene Ihres Codes haben, anstatt innerhalb einer Funktion, wird er verwirrt.

Generell ist es besser, innerhalb einer Funktion zu arbeiten, als auf der obersten Ebene. Auf diese Weise können Sie Ihre Aktivitäten besser organisieren und leichter wiederverwenden. Sie sollten wirklich nur Code haben, der einen Algorithmus außerhalb einer Funktion in einem schnellen und unsauberen Skript ausführt.

Winston Ewert
quelle
1
Ich glaube, es gibt viele gute Gründe, warum Pythonic Variablen auf Modulebene verwendet. Ich denke, dieser Rat ist nur ein Artefakt der Pylint-Fehlinterpretation von PEP8, und unter der Annahme, dass die Umkehrung von "Konstanten sollten auf Modulebene sein" auch wahr sein sollte.
MetricSystem
21

Ja. Gemäß der PEP8-Regel für Konstanten :

Konstanten werden in der Regel auf Modulebene definiert und in Großbuchstaben mit Unterstreichungszeichen zwischen den Wörtern geschrieben. Beispiele hierfür sind MAX_OVERFLOWund TOTAL.

Lange Version:

In der Python-Community gibt es (wie in vielen anderen Communities) Konventionen zum Schreiben von Code. Dies unterscheidet sich vom Arbeitscode : Auch wenn Sie Ihre Konstanten in Kleinbuchstaben schreiben, funktioniert Ihr Code immer noch.

Es gibt jedoch einen Konsens in der Gemeinschaft (wie in PEP8 dokumentiert), der mit Tools wie Pylint "durchgesetzt" wird . Wenn Sie auf Ihr eigenes Glück programmieren, können Sie die Hinweise, die Ihnen pylint gibt, vernachlässigen. Wenn Sie einen offenen Austausch mit der Community wünschen, auch bekannt als »jemand außer mir sollte meinen Code verwenden«, sollten Sie Ihren Code gemäß PEP8 vorbereiten.

Thomas Junk
quelle
7
Andererseits ist es durchaus möglich pylint, etwas falsch zu machen. Python bietet keine Möglichkeit, eine Konstante von einer Variablen zu unterscheiden, ansonsten wird erwartet, dass die Konstante immer den gleichen Wert hat. pylintEs wird davon ausgegangen, dass alles, was nur einmal festgelegt wird und sich nie ändert, eine Konstante ist. Wenn es jedoch nicht als Konstante gedacht ist, kann dies nur ein Artefakt der Implementierung sein. Insbesondere der im Kommentar zur Frage angegebene Code weist Werte auf, die bei jedem Durchlauf unterschiedlich sind. Daher sollten sie nicht als Konstanten betrachtet werden, auch wenn Pylint dies für möglich hält.
Jules
@Jules Ich würde einmal gesetzte Variablen aufrufen und zur Laufzeit nie wieder eine Konstante ändern, daher existiert in vielen Sprachen (zB in JS) ein constSchlüsselwort. Obwohl der Anfangswert anders ist, als vielleicht PI.
Thomas Junk
1
Ich würde zwischen einer unveränderlichen Variablen (dh etwas, das zur Laufzeit festgelegt und nicht geändert wurde) und einer Konstanten (dh etwas, das in jedem Programmlauf gleich ist) unterscheiden. Wenn die Sprache die Möglichkeit dazu bietet, könnte dies zur Kompilierungszeit berechnet werden ) ... der Punkt ist, dass, weil es keine Möglichkeit gibt, die Unterscheidung zu Python zu spezifizieren, pylintdie letztere angenommen wird, selbst wenn die erstere der Fall ist.
Jules
Pylint hat definitiv Unrecht, da es lautete "Konstanten sollten Modulebene sein" und angenommen, dass die Umkehrung "Modulebene sollte Konstanten sein". Aber weil es ansonsten ein gutes, nützliches Werkzeug ist, scheinen wir damit festzuhalten.
MetricSystem
@MetricSystem Welche Funktion hätte Ihrer Meinung nach eine Variable auf Modulebene außer einer Konstanten? Sollte es veränderlich sein?
Thomas Junk
13

Die PEP8- und Python-Community-Norm ist zu verwenden ALL_CAPS_CONSTANTS. Es ist ein allgemeiner visueller Hinweis, der seit Jahrzehnten in C, Java, Perl, PHP, Python, Bash und anderen Programmiersprachen und Shell-Umgebungen verwendet wird. Aber im modernen Online-Sprachgebrauch bedeutet ALL CAPS SCHREIEN . Und schreien ist unhöflich.

Python ist dagegen eher inkonsistent ALL_CAPS_CONSTANTS. JavaScript kann haben Math.PI, aber Python hat math.pi. Es gibt keine erkennbarere oder dauerhaftere Konstante als π. Oder überlegen Sie sys.version_info, welche Version von Python Sie verwenden. 100% konstant über die gesamte Lebensdauer Ihres Programms - weit mehr als PORToder MAX_ITERATIONSoder andere Konstanten , die Sie definieren würden. Oder wie wäre es sys.maxsize? Der maximale native Ganzzahlwert Ihrer Plattform ist nicht nur über ein oder zwei Programmläufe hinweg konstant, sondern über die Lebensdauer Ihrer Hardware.

Wenn diese Konstanten - einschließlich einiger wie π und e, die fundamentale Konstanten des Universums sind und sich nicht über die gesamte Ewigkeit ändern -, wenn sie klein geschrieben werden können, können auch andere Konstanten. Du kannst wählen.

Denken Sie daran, PEP8 ist ein Styleguide . Eine Richtlinie, kein Gesetz. Eine Richtlinie, gegen die häufig sogar Pythons Standardbibliothek verstößt. Und unter Berufung auf eine andere grundlegende Python-Richtlinie, PEP20 (auch bekannt als "The Zen of Python"):

  • Schön ist besser als hässlich
  • Lesbarkeit zählt
  • Praktikabilität schlägt Reinheit.

Auf einer praktischen Anmerkung, wenn ein Programm des YELLY_CONSTANTund SHOUTY_PARAMETERbeginnt zu reiben, hilft es , sich daran zu erinnern , dass die alle Caps Konstanten sind in der Regel nicht wirklich dauerhafte platonisch Ideale , sondern Parameter eines Programmablaufs. Es gibt nichts wirklich Konstantes an PORT, SITENAMEoder NUMRUNS, und sie müssen nicht als eigenständige Programm-Globals verwaltet werden. Beispielsweise können sie als global zugreifbares Bündel von Programmparametern in ein Wörterbuch abgelegt werden:

config = {
    'port': 80,
    'sitename': "Bubba's Blog",
    'numruns': 100,
}

Python verfügt außerdem über eine hervorragende Funktion zur Übergabe von Schlüsselwortparametern, mit der die Verwendung verringert wird APPARENTLY_ANGRY_GLOBAL_VARIABLES:

def process_data(sitename, port=80, numruns=100):
    ...

process_data("Bubba's Blog")

In der Praxis werden (oder sollten) viele dieser Werte aus Konfigurationsdateien, Betriebssystemumgebungsvariablen, Befehlszeilenargumenten oder anderen Quellen gelesen, um die Umkehrung des Steuerprinzips / -musters zu befriedigen . Aber das ist eine größere Geschichte für einen anderen Tag.

Jonathan Eunice
quelle
1

Ja, das ist in den meisten Programmiersprachen durchaus üblich (zumindest in denen, die ich verwende).

Sie können auf diesen Google-Link verweisen, um einen gemeinsamen Stil zwischen Entwicklern desselben Teams zu teilen.

Es wird empfohlen, zu verwenden

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
alain.janinm
quelle