2012-04-21 19 views
5

Piszę paczkę P. W katalogu głównym P znajduje się moduł m0. Gdzieś wewnątrz P istnieją moduły m1, m2, ..., że trzeba importować z M0Najlepszy sposób na importowanie modułu Pythona w katalogu głównym hierarchii pakietów z innego modułu w tym samym pakiecie

Oczywiście można napisać w każdym z tych modułów:

from P.m0 import ... 

Jednak jeśli zmienię nazwę PI muszą ponownie odwiedzić wszystkie miejsca i przepisać takie oświadczenia.

Mogę również użyć importu względnego, ale jeśli przeniesię moduł na innym poziomie w hierarchii pakietów, muszę ustalić liczbę kropek.

Jest kilka innych powodów, ale najważniejsze, naprawdę chcę powiedzieć, import z modułu m0, który znajduje się w katalogu głównym mojego pakietu, jaki jest najlepszy sposób na wyrażenie tego?

+0

Skrót od pisania bardzo introspekcyjnego hacka, takiego jak 'import x', który zmienia' sys.path' lub przesłonięcie semantyki 'builtin .__ import__' lub tworzenie haków importowych zgodnie z sugestiami w http://docs.python.org/library/functions.html#__import__, szukasz bardzo rozsądnej funkcji, która nie istnieje w większości języków, które znam od 2012 roku. W mojej skromnej opinii, python jest lepiej dopasowany niż niektóre inne języki, ale nadal szczególnie źle nadaje się do niewerbalnego importu. "Pythoniczny" pogląd, że taka gadatliwość jest wyraźna, a przez to dobra, prawdopodobnie nie sprawi, że ta funkcja będzie dostępna. – ninjagecko

+0

Wiedziałem, że dostanę to, co jest ważne w tej sprawie, i tak w ogóle przeprowadzasz zasadnicze refaktoryzacje. Pisanie kodu jest cały czas ważnym refaktoryzacją. Pracujesz z kilkoma pakietami, umieszczasz coś w jednym miejscu, potem zdajesz sobie sprawę, że jest to główna funkcjonalność, którą można wykorzystać gdzie indziej, więc zmieniasz ją w inny pakiet. Jest kilka rzeczy, których powinieneś się martwić, gdy poruszasz różne rzeczy Próbuję zminimalizować obciążenie. Nawiasem mówiąc, mam m0 na górze każdej paczki, więc kiedy moduł przenosi się do innej paczki i nadal odnosi się do m0 na górze pierwszego paczki, jest podatny na błędy. – gae123

+0

Tak, zgadzam się. Jednak nie jestem pewien, dlaczego mówisz, co mówisz. Nie pytałem "o co w tym wszystkim chodzi". – ninjagecko

Odpowiedz

1

To niemożliwe.

Jednakże, jeśli wykonujesz znaczącą korektę, gdy poruszasz się między modułami, pomiędzy podpakietami, które mają zaktualizować jakiś względny import, nie jest to poważny problem.

To samo dotyczy zmiany nazwy pakietu najwyższego poziomu, jeśli nie korzystasz z importu względnego - można to zrobić bardzo szybko dzięki wyszukiwaniu i zamianie wszystkich plików.

+0

Uzgodnione - "import" jest wystarczająco skomplikowany, bez dodawania dodatkowej magii, aby naprawić przypadek użycia, który może być obsługiwany przez szybkie wyszukiwanie i zamienianie. – katrielalex

0

Jeśli chcesz trochę zmodyfikować swoje pytanie, możesz sobie z tym poradzić.

JEŻELI jedyne punkty wejścia do twojego pakietu są kontrolowane; na przykład tylko przetestować swój kod wykonując coś jak wywoływanie testsuite package/.../module.py które

wtedy można mieć pewność, że pierwszą rzeczą, jaką możesz zrobić, to import firstthing, aw opakowaniu/firstthing.py masz:

import sys 
import os.path 
packageDir = os.path.split(__name__)[0] 
sys.path[:] = sys.path+[packageDir] # or maybe you want it first... 

Głównym zastrzeżenie, że nie będzie można uruchomić plików Pythona bez przechodzenia przez punkty wejścia. Zawsze chcę to zrobić dla każdego projektu, który piszę w pythonie (aby względny import działał ładnie), ale osobiście uważam, że jest to tak niewygodne, że po prostu się poddaje.


Istnieje również druga alternatywa. To nie jest nierozsądne, aby określić, że twój pakiet wymaga innego pakietu w ścieżce Pythona. Ten pakiet może być pakietem narzędziowym, który wykonuje poważny hack. Na przykład, jeśli nazwa pakietu to "x", możesz zrobić import x, który użyłby modułu inspect do wykonania refleksji na stosie interpretera, pozwalając ci dowiedzieć się, z którego modułu go importujesz. Następnie można zrobić coś w rodzaju "wstecznego przejścia na os.walk", przechodząc do katalogów nadrzędnych, dopóki nie znajdziesz katalogu głównego pakietu (sprawdzając jakiś specjalny plik wskaźnika, manifest lub coś podobnego). Następnie programowalibyśmy programowo powyższą modyfikację ścieżki Pythona poprzez sys.path. Jest taki sam jak powyżej, ale masz swobodę robienia takich rzeczy jak uruchamianie dowolnego pliku Pythona bez konieczności przechodzenia przez okropny punkt początkowy.

Jeśli masz ekstremalną kontrolę nad otoczeniem powłoki, możesz także po prostu zwiększyć wartość zmiennej PYTHONPATH, aby uwzględnić katalog paczek, ale jest to bardzo delikatne pod wieloma względami i raczej nieeleganckie.

Powiązane problemy