Antworten:
Dies hat nichts mit Python zu tun. Globale Variablen sind in jeder Programmiersprache schlecht.
Globale Konstanten sind jedoch konzeptionell nicht mit globalen Variablen identisch . globale Konstanten sind vollkommen harmlos. In Python erfolgt die Unterscheidung zwischen den beiden rein konventionell: CONSTANTS_ARE_CAPITALIZED
und globals_are_not
.
Der Grund, warum globale Variablen schlecht sind, besteht darin, dass Funktionen versteckte (nicht offensichtliche, überraschende, schwer zu erkennende, schwer zu diagnostizierende) Nebenwirkungen haben, die zu einer Zunahme der Komplexität führen und möglicherweise zu Spaghetti-Code führen .
Eine vernünftige Verwendung des globalen Zustands ist jedoch akzeptabel (ebenso wie der lokale Zustand und die Veränderlichkeit), selbst bei der funktionalen Programmierung, entweder zur Algorithmusoptimierung, zur Reduzierung der Komplexität, zum Zwischenspeichern und zur Memoisierung oder zur praktischen Anwendbarkeit von Portierungsstrukturen, die aus einer überwiegend imperativen Codebasis stammen.
Alles in allem kann Ihre Frage auf viele Arten beantwortet werden. Am besten googeln Sie einfach "Warum sind globale Variablen schlecht?". Einige Beispiele:
Wenn Sie tiefer gehen und herausfinden möchten, warum es um Nebenwirkungen und viele andere aufschlussreiche Dinge geht, sollten Sie die funktionale Programmierung lernen:
Ja, theoretisch sind Globale (und "Staat" im Allgemeinen) böse. In der Praxis werden Sie feststellen, dass die meisten Module dort mit einer Reihe globaler Deklarationen beginnen, wenn Sie in das Paketverzeichnis Ihres Pythons schauen. Offensichtlich haben die Leute kein Problem mit ihnen.
Speziell für Python ist die Sichtbarkeit von Globals auf ein Modul beschränkt, daher gibt es keine "echten" Globals, die das gesamte Programm betreffen - das macht sie weniger schädlich. Ein weiterer Punkt: Es gibt keine const
. Wenn Sie also eine Konstante benötigen, müssen Sie eine globale verwenden.
Wenn ich in meiner Praxis ein globales Element in einer Funktion ändere, deklariere ich es immer mit global
, auch wenn dies technisch nicht erforderlich ist, wie in:
cache = {}
def foo(args):
global cache
cache[args] = ...
Dies erleichtert das Aufspüren der Manipulationen von Globals.
Eine persönliche Meinung zu diesem Thema ist, dass die Verwendung globaler Variablen in einer Funktionslogik bedeutet, dass ein anderer Code die Logik und die erwartete Ausgabe dieser Funktion ändern kann, was das Debuggen sehr schwierig macht (insbesondere in großen Projekten) und das Testen erschwert auch.
Wenn Sie andere Personen berücksichtigen, die Ihren Code lesen (Open-Source-Community, Kollegen usw.), fällt es ihnen außerdem schwer zu verstehen, wo die globale Variable festgelegt wird, wo sie geändert wurde und was von dieser globalen Variablen im Gegensatz zu erwarten ist zu einer isolierten Funktion, deren Funktionalität durch Lesen der Funktionsdefinition selbst bestimmt werden kann.
Ich glaube, dass ein sauberer und (fast) fehlerfreier Code Funktionen haben sollte, die so rein wie möglich sind (siehe reine Funktionen ). Eine reine Funktion hat folgende Bedingungen:
Wenn globale Variablen vorhanden sind, wird mindestens einer der oben genannten Punkte verletzt, wenn nicht beide als externer Code zu unerwarteten Ergebnissen führen können.
Eine weitere klare Definition von reinen Funktionen: "Die reine Funktion ist eine Funktion, die alle ihre Eingaben als explizite Argumente verwendet und alle ihre Ausgaben als explizite Ergebnisse erzeugt ." [1] . Globale Variablen zu haben, verstößt gegen die Idee reiner Funktionen, da eine Eingabe und möglicherweise eine der Ausgaben (die globale Variable) nicht explizit angegeben oder zurückgegeben wird.
Weiter , dass, wenn Sie Unit-Test und dem ersten Prinzip überlegen ( F ast Tests I ndependent Tests, R epeatable, S Elf-Validieren und T imely) wird verletzen wahrscheinlich die Unabhängige Prinzip testet (was bedeutet , dass Tests hängt nicht auf einander).
Eine globale Variable zu haben (nicht immer), aber in den meisten Fällen (zumindest was ich bisher gesehen habe) besteht darin, Ergebnisse vorzubereiten und an andere Funktionen weiterzugeben. Dies verstößt ebenfalls gegen dieses Prinzip. Wenn die globale Variable auf diese Weise verwendet wurde (dh die in Funktion X verwendete globale Variable muss zuerst in einer Funktion Y gesetzt werden), bedeutet dies, dass Sie für die Einheitentestfunktion X zuerst die Test- / Ausführungsfunktion Y ausführen müssen.
Andererseits und wie bereits erwähnt, kann es etwas besser sein, wenn die globale Variable als "konstante" Variable verwendet wird, da die Sprache keine Konstanten unterstützt. Ich arbeite jedoch immer lieber mit Klassen und habe die "Konstanten" als Klassenmitglied und verwende überhaupt keine globale Variable. Wenn Sie einen Code haben, den zwei verschiedene Klassen benötigen, um eine globale Variable gemeinsam zu nutzen, müssen Sie wahrscheinlich Ihre Lösung umgestalten und Ihre Klassen unabhängig machen.
Ich glaube nicht, dass Globals nicht verwendet werden sollten. Wenn sie jedoch verwendet werden, sollten die Autoren einige Prinzipien (die oben genannten vielleicht und andere Prinzipien und bewährte Methoden der Softwareentwicklung) für einen saubereren und nahezu fehlerfreien Code berücksichtigen.
Sie sind wichtig, der Bildschirm ist ein gutes Beispiel. In einer Multithread-Umgebung oder mit vielen beteiligten Entwicklern stellt sich in der Praxis jedoch häufig die Frage: Wer hat sie (fälschlicherweise) festgelegt oder gelöscht? Abhängig von der Architektur kann die Analyse kostspielig sein und häufig erforderlich sein. Während das Lesen der globalen Variable in Ordnung sein kann, muss das Schreiben darauf gesteuert werden, beispielsweise durch einen einzelnen Thread oder eine threadsichere Klasse. Daher entstehen bei globalen Vars die Angst vor hohen Entwicklungskosten, die durch die Folgen möglich sind, für die sie selbst als böse gelten. Daher ist es im Allgemeinen empfehlenswert, die Anzahl der globalen Variablen niedrig zu halten.
eval
,import *
, String - Verkettung , variableid
, Attribut Schatten )