2013-05-03 12 views
6

Tak, widziałem kilka podobnych pytań na Stack Overflow, ale nic nie wydaje się rozwiązać mój problem, lub ogólny przypadek. Mam nadzieję, że to pytanie naprawi to i powstrzyma moje bóle głowy. Mam repo git w postaci:Importowanie z podkatalogów siostry w Pythonie?

repo/ 
    __init__.py 
    sub1/ 
     __init__.py 
     sub1a/ 
     __init.py 
     mod1.py 
    sub2/ 
     __init__.py 
     mod2.py 

Jak importować mod2.py z mod1.py i odwrotnie, i jak to zmienić w zależności od tego, czy mod1.py lub mod2.py są skrypty (gdy każdy odpowiednio importuje - nie jest importowany)?

Odpowiedz

6

Najprostszym rozwiązaniem jest umieszczenie katalogu zawierającego repo w swoim PYTHONPATH, a następnie po prostu użycie importu ścieżek bezwzględnych, np. import repo.sub2.mod2 i tak dalej.

Każde inne rozwiązanie będzie się wiązać pewne hackery jeśli chcesz, aby objąć przypadki, gdzie jesteś powołujące oba pliki Pythona bezpośrednio jako skrypty z dowolnych katalogów - najprawdopodobniej sys.path maglowania, aby skutecznie osiągnąć to samo jak ustawienie PYTHONPATH, ale bez konieczności ustawiania go przez użytkownika.

+1

Nie mam nic przeciwko edycji PYTHONPATH, ale czy istnieje standardowy sposób na wymuszenie tego? Nie chcę, aby wszyscy nowi użytkownicy repo musieli ręcznie wchodzić i aktualizować swoją PYTHONPATH. – Eli

+1

Jeśli nie chcesz, aby ludzie sami zarządzali 'PYTHONPATH', może być konieczne rozważenie' sys.path' mangling. (Np. Użyj '__file__' oraz' os.abspath', aby sprawdzić, gdzie znajduje się skrypt, a następnie pobierz katalog, którego odpowiednia liczba poziomów jest nadrzędna, a następnie 'sys.path.insert 'it.) – Amber

2

Jeśli używasz Python 2.6+, masz dwie możliwości:

  • importu względem
  • Dodawanie repo do swojej PYTHONPATH

z importem względnych, specjalna składnia kropka jest używana:

w pakiecie sub1:

from .sub2.mod2 import thing 

w opakowaniu sub1a:

from ..sub2.mod2 import otherthing 

Należy pamiętać, że zwykłe oświadczenia importu (import module) nie działają z importu względnych.

Lepszym rozwiązaniem byłoby za pomocą importu absolutnych ze swojej ścieżce Pythona ustawiony prawidłowo (przykład w bash):

export PYTHONPATH=/where/your/project/is:$PYTHONPATH 

Więcej informacji:

+0

Naprawdę chciałem, aby te względne importowanie działało. Jednak na moim python 2.7, nie działają. –

+0

Używając Pythona 2.7, odniosłem sukces używając instrukcji takich jak 'from sub2.mod2 import thing'. – coralvanda

0

skryptu lub moduł importu modułów, albo

  1. na drodze systemu lub
  2. część tego samego pakietu, importera skryptu/modułu.

W przypadku modułów obowiązują te zasady bez wyjątku. W przypadku skryptów obowiązują reguły, ale zmarszczka jest taka, że ​​domyślnie po uruchomieniu skryptu nie jest ona uważana za część pakietu.

Oznacza to, że domyślnie skrypt może importować tylko moduły znajdujące się w ścieżce systemowej. Domyślnie ścieżka zawiera katalog bieżący, więc jeśli uruchomisz skrypt, możesz zaimportować moduły do ​​tego samego katalogu lub do pakietów, które są podkatalogami. Ale to jest to. Skrypt nie ma pojęcia "gdzie to jest" w drzewie katalogów, więc nie może wykonywać żadnych importów, które wymagają określonych względnych informacji o ścieżkach dotyczących zamykania katalogów. Oznacza to, że nie można importować rzeczy "z katalogu nadrzędnego" lub "z katalogu rodzeństwa". Rzeczy znajdujące się w tych katalogach można importować tylko wtedy, gdy znajdują się one na ścieżce systemowej.

Jeśli chcesz, aby skrypt "wiedział", że jest w pakiecie, możesz nadać mu atrybut __package__. Zobacz this previous question. Można wtedy użyć normalnych importów względnych (np. from ...sub2 import mod2) z poziomu tego skryptu.

Powiązane problemy