2011-09-21 12 views
5

Po pierwsze, przepraszam, jeśli to pytanie zostało już zadane w innym miejscu. Naprawdę go szukałem, ale niczego nie znalazłem.Moduł importu modułu submoduł

Sytuacja jest następująca: W folderze mod, mam pliki __init__.py i sub.py. Zawierają one następujące dane: __init__.py:

print "mod" 

sub.py:

import __init__ 
print "sub" 

Teraz wykonaj następujące czynności:

>>> import mod 
mod 
>>> import mod.sub 
mod 
sub 

Ale kiedy robi import mod.sub, dlaczego mod/__init__.py ponownie wykonywane? Zostało już zaimportowane. Ta sama cecha występuje dziwne, gdybyśmy po prostu zadzwoń:

>>> import mod.sub 
mod 
mod 
sub 

mogę zmienić zachowanie zmieniając import __init__? Ta linia wydaje mi się najprawdopodobniej niesłuszna.

+0

Dlaczego mówisz "import __init__" w sub.py ?? – rocksportrocker

+0

Ponieważ moduł podstawowy 'mod' zawiera klasy współużytkowane, które są subklasowane w' pod'. – Turion

Odpowiedz

1

należy wymienić

import __init__ 

przez

import mod 
+0

Uważam za sprzeczne z intuicją, że to działa. W końcu jesteśmy już w folderze 'mod' i pomyślałem, że interpreter będzie szukał pliku' mod.py'. – Turion

7

Rzeczywiście można sprawdzić, co dzieje się za pomocą słownika sys.modules. Python decyduje się przeładować moduł w zależności od kluczy w tym słowniku.

Po uruchomieniu import mod tworzy jeden wpis, mod w sys.modules.

Po uruchomieniu import mod.sub, po wywołaniu import __init__, Python sprawdza czy klucz mod.__init__ w sys.modules, ale nie ma takiego klawisza, więc jest ponownie importowana.

Najważniejsze jest to, że Python decyduje się na ponowny import modułu za pomocą kluczy znajdujących się w sys.modules, nie dlatego, że faktyczny moduł został już zaimportowany.

+0

Dobre wyjaśnienie, dzięki. – Turion

0

Dla kompletności, znalazłem inne rozwiązanie gry z importu względna:

Wymień

import __init__ 

przez

from . import __init__ 

Ale ja nie rozumiem, dlaczego to działa.

edytuj: To w rzeczywistości nie działa. wynikowy __init__ nie jest modułem mod, ale czymś innym o typie method-wrapper. Teraz jestem całkowicie zdezorientowany.

Powiązane problemy