webentwicklung-frage-antwort-db.com.de

Warum sind globale Variablen böse?

Ich habe versucht, eine gute Quelle zu finden, die erklärt, warum die Verwendung von global in python (und in der Programmierung im Allgemeinen) als schlechte Praxis angesehen wird. Kann mich jemand darauf hinweisen eins oder hier erklären?

92
LarsVegas

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. Es ist nur so, dass es in Python) keinen erzwungenen Unterschied gibt, nur durch Konvention sind CONSTANTS_CAPITALIZED und globals_are_not.

Der Grund, warum sie schlecht sind, ist, dass sie Funktionen erlauben, versteckte (nicht offensichtliche, überraschende, schwer zu erkennende) Nebenwirkungen zu haben, die zu einer Zunahme der Komplexität führen und möglicherweise zu Spaghetti-Code führen.

Die vernünftige Verwendung des globalen Zustands ist jedoch akzeptabel (ebenso wie der lokale Zustand und die Veränderbarkeit), selbst bei der funktionalen Programmierung, entweder zur Optimierung von Algorithmen, zur Reduzierung der Komplexität, zum Zwischenspeichern und Speichern oder zur praktischen Durchführung von Portierungsstrukturen, die ihren Ursprung in einer überwiegend zwingenden Codebasis haben.

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 Functional Programming lernen:

123
Erik Allik

Ja, in der Theorie, Globale (und "Staat" im Allgemeinen) sind 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 kein const. Wenn Sie also eine Konstante benötigen, müssen Sie ein globales verwenden.

Wenn ich in meiner Praxis ein Global 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.

28
georg

Eine persönliche Meinung zu diesem Thema ist, dass globale Variablen, die in einer Funktionslogik verwendet werden, bedeuten, dass ein anderer Code die Logik und die erwartete Ausgabe dieser Funktion ändern kann, was das Debuggen (insbesondere in großen Projekten) sehr erschwert und das Testen erschwert auch.

Wenn Sie andere Personen in Betracht ziehen, die Ihren Code lesen (Open-Source-Community, Kollegen usw.), wird es ihnen schwer fallen, zu verstehen, wo die globale Variable festgelegt wird, wo sie geändert wurde und was sie von dieser globalen Variablen erwarten können für eine isolierte Funktion, dass ihre Funktionalität durch Lesen der Funktionsdefinition selbst bestimmt werden kann.

(Wahrscheinlich) Verstoß gegen die Definition der reinen Funktion

Ich glaube, dass ein sauberer und (fast) fehlerfreier Code Funktionen haben sollte, die so rein wie möglich sind (siehe pure functions ). Eine reine Funktion ist diejenige, die die folgenden Bedingungen hat:

  1. Die Funktion wertet bei gleichen Argumentwerten immer den gleichen Ergebniswert aus. Der Funktionsergebniswert kann weder von verborgenen Informationen oder Zuständen abhängen, die sich während der Programmausführung oder zwischen verschiedenen Programmausführungen ändern, noch von externen Eingaben von E/A-Geräten (normalerweise - siehe unten).
  2. Auswertung des Ergebnisses verursacht keine semantisch beobachtbaren Nebeneffekte oder Ausgaben, z. B. Mutation von veränderlichen Objekten oder Ausgabe an E/A-Geräte.

Wenn globale Variablen vorhanden sind, wird mindestens eine der oben genannten Bedingungen verletzt, wenn nicht beide als externer Code vorliegen, kann dies möglicherweise zu unerwarteten Ergebnissen führen.

Eine weitere klare Definition von reinen Funktionen: "Reine Funktion ist eine Funktion, die alle ihre Eingaben als explizite Argumente verwendet und alle ihre Ausgaben als explizite Ergebnisse erzeugt. " [1] . Globale Variablen verstoßen gegen die Vorstellung von reinen Funktionen, da eine Eingabe und möglicherweise eine der Ausgaben (die globale Variable) nicht explizit angegeben oder zurückgegeben wird.

(Wahrscheinlich) Verstoß gegen das Unit-Testing-Prinzip von F.I.R.S.T.

Wenn Sie weiter Unit-Tests und das FIRST-Prinzip ( [~ # ~] f [~ # ~] ast-Tests in Betracht ziehen, [~ # ~] i [~ # ~] nabhängige Tests, [~ # ~] r [~ # ~] epeatable, [~ # ~] s [~ # ~] elf-Validating und [~ # ~] t [~ # ~] verletzen wahrscheinlich das Prinzip der unabhängigen Tests (was bedeutet, dass die Tests nicht voneinander abhängig sind).

Eine globale Variable zu haben (nicht immer), aber in den meisten Fällen (zumindest was ich bisher gesehen habe) ist, Ergebnisse vorzubereiten und an andere Funktionen weiterzugeben. Dies verstößt ebenfalls gegen dieses Prinzip. Wenn die globale Variable auf diese Weise verwendet wurde (d. H. Die in Funktion X verwendete globale Variable muss zuerst in einer Funktion Y festgelegt werden), bedeutet dies, dass Sie für die Einheitentestfunktion X zuerst die Test-/Ausführungsfunktion Y ausführen müssen.

Globale als Konstanten

Andererseits und wie andere Leute bereits erwähnt haben, kann es etwas besser sein, wenn die globale Variable als "konstante" Variable verwendet wird, da die Sprache keine Konstanten unterstützt. Ich bevorzuge es jedoch immer, mit Klassen zu arbeiten und die "Konstanten" als Klassenmitglied zu haben und überhaupt keine globale Variable zu verwenden. 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 Globale nicht verwendet werden sollten. Wenn sie jedoch verwendet werden, sollten die Autoren einige Prinzipien berücksichtigen (die oben vielleicht genannten und andere Prinzipien und bewährte Methoden des Software-Engineerings), um einen saubereren und nahezu fehlerfreien Code zu erhalten.

9
Rafael

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 (irrtümlich) 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 Thread-sichere Klasse. Globale Variablen haben daher die Angst vor hohen Entwicklungskosten, die durch die Konsequenzen, für die sie selbst als böse gelten, verursacht werden können. Im Allgemeinen ist es daher empfehlenswert, die Anzahl der globalen Variablen niedrig zu halten.

3