main.py:
%Vor%subone.py:
%Vor%subtw.py:
%Vor% Running python main.py
löst eine NameError: name 'subone' is not defined
aus. Ich habe erwartet, dass es "abc" druckt.
Das Refactoring für die Verwendung von from
import
und Klassen hilft nicht:
main.py:
%Vor%subone.py:
%Vor%subtw.py:
%Vor% ABER es wird von main.py: def 'drucken. (Dies funktioniert auch, wenn import
verwendet wird.)
Warum funktioniert das so? Es scheint, als ob subone
importiert wird, sollte es für subtwo
verfügbar sein.
Liegt es daran, dass importierte Module voneinander abhängig sind, ohne dass sie ihr "Eltern" -Modul durchlaufen müssen? Gibt es einen anderen, üblichen Weg, dies zu tun?
Ich verstehe jetzt, dass das erste Beispiel nicht funktionieren wird, weil die Zeile print subone.a
den Namen subone
nicht erkennt, obwohl sie nicht im subtwo
s Namespace ist in main.py
's) und wird innerhalb des Moduls subtwo
aufgerufen. Dies kann behoben werden, indem import subone
am Anfang von subtwo.py
verwendet wird - es lädt das Modul nicht neu, sondern fügt es dem% code%% namespace hinzu, so dass subtwo
es benutzen kann.
Aber was ist damit:
main.py:
%Vor%subone.py:
%Vor%subtw.py:
%Vor% Ich würde denken, dass, da subtwo
und Wrap
beide direkt in den Namespace von Nugget
geladen werden, sie den Namespace von main
benutzen und sich gegenseitig referenzieren können, aber ein% wirft Code%. IS IT, weil main
von im Namespace NameError: name 'Nugget' is not defined
vor dem Laden in den Namespace von Wrap
ausgewertet / überprüft wird?
Wenn Sie Ihre subtw.py so geändert haben, funktioniert es
%Vor%Wenn Sie in subtwo.py subone.a verwenden, versuchen Sie, auf den Namespace subone in subtwo.py zuzugreifen, und im Namespace "subone" sollte ein Attribut "a" vorhanden sein.
Wenn Sie subone in subwoo.py importieren, wird Subone zum Namespace hinzugefügt und subone Namespace hat das Attribut a. also wird subone.a funktionieren.
Ich würde auch vorschlagen, dass Sie mit dir () spielen, um zu sehen, wie Namespaces hinzugefügt werden.
In subtw.py können Sie Folgendes tun:
%Vor%Versuchen Sie auch, "print dir ()" vor und nach Ihren Importanweisungen hinzuzufügen, und die Idee sollte Ihnen klar werden.
"import x" fügt 'x' zu den aktuellen Modulen hinzu Namespace während "von x importieren *" wird Fügen Sie alle Attribute auf Modulebene hinzu direkt in den aktuellen Modulnamensraum
In Ihrem obigen ersten Beispiel von main.py, subone.py und subtwo.py enthält der Namespace in main.py "subone" und "subtwo", während subtwo.py einen leeren Namespace und kann nicht auf subone.a zugreifen.
[Bearbeiten: Einige weitere Erklärungen] Betrachten Sie folgende Dateien: main.py
%Vor%subone.py
%Vor%subtw.py
%Vor%Und die Ausgabe von laufendem main.py:
%Vor%Einige Beobachtungen
Können Sie erklären, warum Sie subone subone haben sollten, wenn subone von main importiert wurde? So kann subtwo.py kompiliert werden, ohne zu wissen, was main.py importiert hat.
Wenn ein zweites Programm subtw.py importiert, hängt das subwoo-Wissen über subone davon ab, welches der beiden Hauptprogramme unterzulegen ist? Dies würde die Wiederverwendbarkeit von unter zwei reduzieren.
Es scheint, als ob Sie die Kompilierung als einen Prozess mit einer definierten Reihenfolge betrachten, die Zustandsinformationen akkumuliert: compile main.py, währenddessen wir subone.py kompilieren / importieren, Informationen daraus sammeln und dann kompilieren / Importieren Sie subtw.py, indem Sie die Informationen verwenden, die wir bereits gesammelt haben.
Stattdessen ist die Kompilierung jedes Moduls unabhängig von anderen, sofern keine Abhängigkeiten deklariert sind. Dies macht die Wiederverwendung und Pflege von Code wesentlich einfacher: Es gibt weniger versteckte Abhängigkeiten.
Liegt es daran, dass es schlecht programmiert ist? importierte Module hängen von jedem ab andere ohne durch ihre zu gehen 'Eltern' Modul?
Nicht als solches ... Es ist einfach eine schlechte Programmierung, Modul 2 von Modul 1 abhängig zu machen, ohne es zu sagen , d. h. ohne Modul 2 zu deklarieren "Ich bin von Modul 1 abhängig".
Was Ihr zweites Beispiel betrifft, weiß "main.py" über Nugget
, aber "subtwo.py" nicht.
Ich denke, es würde helfen, so darüber nachzudenken. Jedes Modul (Datei) muss so funktionieren, als wären nur die anderen Module vorhanden, die es importiert. In diesem Fall könnte "subtwo.py" nicht von selbst ausgeführt werden, da Nugget
nicht importiert wurde. Im Wesentlichen weiß "subtwo.py" nicht, was "main.py" weiß. Es sollte nicht, weil es von irgendwoher von irgendwem aufgerufen werden kann, und es kann sich nicht darauf verlassen, dass jemand anderes das Zeug importiert, das es braucht.
Dies liegt daran, dass die importierten Module eigene Namespaces haben. Was du geschrieben hast ist sehr ähnlich wie:
%Vor% Die Module haben ihre Namespaces lokal, und wenn Sie from subone import *
verwenden, importieren Sie den Namespace NUR in main.py
Namespace, auf den von subtwo
nicht zugegriffen werden kann.
Trotzdem - was Sie versuchen, ist eine sehr schlechte Übung. Vermeiden Sie globale Variablen und import *
, nur weil Sie mehr und mehr verwirrt werden, wie jetzt.
Mehr dazu: Ссылка
und vielleicht: Ссылка