Gibt es in Python ein Äquivalent von Fortrans "impliziter None"?

8

In Fortran gibt es eine Anweisung Implicit none , die einen Kompilierungsfehler auslöst, wenn eine lokale Variable nicht deklariert, aber verwendet wird. Ich verstehe, dass Python eine dynamisch typisierte Sprache ist und der Umfang einer Variablen zur Laufzeit bestimmt werden kann.

Aber ich möchte gewisse unbeabsichtigte Fehler vermeiden, die auftreten, wenn ich vergesse, eine lokale Variable zu initialisieren, sie aber im Hauptcode zu verwenden. Zum Beispiel ist die Variable x im folgenden Code global, obwohl ich das nicht beabsichtigt habe:

%Vor%

Meine Frage ist also: Gibt es eine Möglichkeit sicherzustellen, dass alle Variablen, die in test() verwendet werden, lokal sind und dass es keine Nebenwirkungen gibt. Ich benutze Python 2.7.x. Falls es eine lokale Variable gibt, wird ein Fehler ausgegeben.

    
Corrupted MyStack 17.07.2015, 03:33
quelle

8 Antworten

7
  

Meine Frage ist also: Gibt es eine Möglichkeit, alle verwendeten Variablen sicherzustellen?   in test () sind lokal und es gibt keine Nebenwirkungen.

Es gibt eine Technik, um zu validieren, dass auf globale Variablen nicht zugegriffen wird.

Hier ist ein Decorator, der die Opcodes einer Funktion nach einem LOAD_GLOBAL scannt.

%Vor%

Um dies praktisch zu machen, werden Sie eine Stop-Liste von akzeptablen globalen Referenzen (d. h. Modulen) wünschen. Die Technik kann erweitert werden, um andere Opcodes wie STORE_GLOBAL und DELETE_GLOBAL abzudecken.

Alles, was gesagt wurde, ich sehe keinen direkten Weg, um Nebenwirkungen zu entdecken.

    
Raymond Hettinger 17.07.2015 04:09
quelle
3

Es gibt keine implizite None in dem Sinne, den du meinst. Zuweisung wird eine neue Variable erstellen, daher kann ein Tippfehler einen neuen Namen in den Bereich einfügen.

Eine Möglichkeit, den gewünschten Effekt zu erzielen, ist der folgende hässliche Hack:

%Vor%

Wenn Sie also Ihre Funktion test mit dem no_globals -Wrapper deklarieren, erhalten Sie einen Fehler, so:

%Vor%     
Roshan Mathews 17.07.2015 04:01
quelle
0

Vermeiden Sie es, global gültige Variablen zu verwenden. Und wenn Sie müssen, fügen Sie ihren Namen ein Präfix voran, das Sie niemals in einem lokalen Variablennamen verwenden werden.

    
Jonathon Reinhart 17.07.2015 03:35
quelle
0

Wenn Sie sich darüber wirklich Sorgen machten, könnten Sie Folgendes versuchen:

%Vor%

Aber ich würde empfehlen, beim Schreiben einer Funktion einfach darauf achtsam zu sein, dass Sie nicht versuchen, die Dinge zu referenzieren, bevor Sie sie zuweisen. Wenn möglich, versuchen Sie jede Funktion einzeln zu testen, mit einer Vielzahl von sorgfältig definierten Eingängen und beabsichtigten Ausgaben. Es gibt eine Vielzahl von Testsuiten und Strategien , ganz zu schweigen von den einfachen assert Schlüsselwort.

    
TigerhawkT3 17.07.2015 04:05
quelle
0

In Python ist das ganz einfach legal. In der Tat ist es eine Stärke der Sprache! Dieser (Mangel-) Fehler ist der Grund, warum Sie so etwas tun können:

%Vor%

Während in C müssten Sie " function2 " deklarieren.

Es gibt statische Syntax-Checker (wie flake8 ) für Python, die viel arbeiten, um Fehler zu finden und Schlechter Stil, aber das ist kein Fehler und wird von einem solchen Checker nicht erfasst. Andernfalls wäre so etwas ein Fehler:

%Vor%

Oder etwas noch Grundlegenderes wäre ein Fehler:

%Vor%

Das Beste, was Sie tun können, ist die Verwendung einer anderen Namenskonvention (wie ALL_CAPS) für Deklarationen auf Modulebene. Machen Sie es sich zur Gewohnheit, den gesamten Code in eine Funktion zu stellen (keine Logik auf Modulebene), um zu verhindern, dass Variablen in den globalen Namespace gelangen.

    
brenns10 17.07.2015 03:53
quelle
0
  

Gibt es eine Möglichkeit, sicherzustellen, dass alle in test () verwendeten Variablen lokal sind und dass es keine Nebenwirkungen gibt.

Nein. Die Sprache bietet keine solche Funktionalität.

Es gibt die eingebaute Funktion locals() . Du könntest also schreiben:

%Vor%

aber ich kann mir nicht vorstellen, dass irgendjemand das als Verbesserung betrachtet.

    
David Heffernan 17.07.2015 04:31
quelle
0

Um sicherzustellen, dass die richtige Variable verwendet wird, müssen Sie den Suchbereich einschränken. Innerhalb einer Funktion sucht Python nach Argumenten, die in Zeile definiert sind, und dann nach args und kwargs . Nach diesen wird es außerhalb der Funktion aussehen. Dies kann zu lästigen Fehlern führen, wenn die Funktion von einer globalen Variablen abhängt, die an anderer Stelle geändert wird.

Um zu vermeiden, dass Sie versehentlich eine globale Variable verwenden, können Sie die Funktion mit einem Schlüsselwortargument für die Variablen definieren, die Sie verwenden möchten:

%Vor%

Ich schätze, Sie wollen das nicht für viele Variablen tun. Es wird jedoch die Verwendung von Globals stoppen.

Eigentlich , selbst wenn Sie eine globale Variable in der Funktion verwenden möchten, ist es am besten, sie explizit zu machen:

%Vor%

In diesem Beispiel wird x = 2 für die Funktion verwendet, unabhängig davon, was danach mit dem globalen Wert von x geschieht. Innerhalb der Funktion wird x auf den Wert festgelegt, den sie zur Kompilierzeit hatte.

Ich habe angefangen, globale Variablen als Schlüsselwortargumente zu übergeben, nachdem ich ein paar Mal gebrannt habe. Ich denke, das wird allgemein als gute Praxis angesehen.

    
Will Martin 17.07.2015 20:10
quelle
0

Die angebotenen Lösungen sind interessant, besonders die mit dis.dis , aber Sie denken wirklich in die falsche Richtung. Sie wollen nicht solch einen lästigen Code schreiben.

  • Haben Sie Angst, dass Sie versehentlich ein globales erreichen? Dann schreibe keine Globals. Der Zweck von Modul Globals ist meist zu erreichen. (In einem Kommentar habe ich gelesen, dass Sie 50 Globals im Umfang haben, was mir scheint, dass Sie einige Designfehler haben).

  • Wenn Sie immer noch globale Variablen benötigen, verwenden Sie entweder eine Namenskonvention (UPPER_CASE wird für Konstanten empfohlen, die Ihre Fälle abdecken könnte).

  • Wenn auch eine Namenskonvention keine Option ist, fügen Sie einfach die Funktionen, die Sie nicht global erreichen wollen, in ein separates Modul ein und definieren Sie dort keine Globals. Definieren Sie zum Beispiel pure_funcs und innerhalb dieses Moduls schreiben Sie Ihre "reinen" Funktionen dort und importieren Sie dann dieses Modul. Da Python über einen lexikalischen Geltungsbereich verfügt, können Funktionen only nur Variablen erreichen, die in den äußeren Bereichen des Moduls definiert sind, in dem sie geschrieben wurden (natürlich auch Locals oder Einbauten). Etwas wie das:

    %Vor%
bgusach 22.07.2015 07:13
quelle

Tags und Links