main.py:
%Vor%Paket / __ init __. py:
%Vor%Paket / foo.py:
%Vor%Execute main.py wird wie folgt ausgeben:
%Vor% Der import
in __init__.py
hat nicht wie erwartet funktioniert.
Beachten Sie, dass der globale Namespace ein 'foo' hat, das nur an lokale 'mod'
Sogar a %Code% kann nicht verhindern, dass der globale Namespace geändert wird
Wie konnte das passieren?
Ah! Tricky, aber ich habe es!
"foo" ist kein einfaches "anderes Paket" - es scheint Python als ein Untermodul Ihres "Paket" -Moduls zu erscheinen.
Wenn Sie "package" zum ersten Mal ausführen - entweder aus einem externen Skript importieren oder mit der Befehlszeilenoption -m
ausführen (aber nicht, wenn Sie python package/__init__.py
direkt über die Befehlszeile ausführen), das Paket "Das Modul wird analysiert und zum sys.modules
dictitionary (im Modul sys
) hinzugefügt.
Wenn das Untermodul foo
gelesen wird, wird es nicht nur direkt unter sys.modules
unter dem Schlüssel ["package.foo"]
platziert, sondern auch als Attribut für das übergeordnete Modul. Daher wäre es in Ihrer Python-App als package.foo
verfügbar. Was passiert, wenn das Setzen eines Attributs in sys.modules["package"]
den gleichen Effekt hat wie das Setzen eines Schlüssels in package/__init__.py
globals in Runtime. Das ist was passiert.
Ich hoffe, ich könnte den Prozess richtig in Worte fassen - wenn nicht, frage einfach nochmal nach kommentieren.
-
Da dies wahrscheinlich in realem Code geschieht, den Sie haben, und das Äquivalent von "do_import" von Code außerhalb Ihres Pakets aufgerufen wird (und die Nebeneffekte hat, Ihre Untermodule im globalen Namespace des Pakets erscheinen zu lassen), gibt es kein einfaches Arbeite auf dem Weg herum, den du machst. Mein Vorschlag ist, nur einen Unterstrich ( _
) am Anfang der Untermodulnamen hinzuzufügen, wenn sie nicht aus allgemeinem Code von außerhalb des Pakets aufgerufen werden sollen. (Es wird auch nicht angezeigt, wenn jemand from package import *
in diesem Fall tut)
Tags und Links python