Mam następującą strukturę folderów.
application/app/folder/file.py
i chcę zaimportować niektóre funkcje z file.py do innego pliku Python, który znajduje się w
application/app2/some_folder/some_file.py
próbowałem
from application.app.folder.file import func_name
i kilka innych prób, ale jak dotąd nie udało mi się poprawnie zaimportować. W jaki sposób mogę to zrobić?
Odpowiedzi:
Domyślnie nie możesz. Podczas importowania pliku Python przeszukuje tylko bieżący katalog, katalog, z którego działa skrypt punktu wejścia, i
sys.path
który zawiera lokalizacje, takie jak katalog instalacyjny pakietu (w rzeczywistości jest nieco bardziej złożony niż ten, ale obejmuje większość przypadków) .Możesz jednak dodać do ścieżki Pythona w czasie wykonywania:
źródło
sys.path.append('/path/to/application/app/folder')
jest czystszy imosys.path
zwracalist
, a niedeque
, i to byłoby głupie, aby przekonwertowaćlist
Dodeque
iz powrotem.Nic złego w:
Tylko upewnij się, że
folder
zawiera również__init__.py
, pozwala to na dołączenie go jako pakietu. Nie jestem pewien, o czym mówią inne odpowiedziPYTHONPATH
.źródło
PYTHONPATH
konieczna jest modyfikacja . Załóżmy, że masz dwa foldery na tym samym poziomie:A
iB
.A
posiada__init.py__
. Spróbuj zaimportować coś zB
wewnątrzA
.init.py
lub__init__.py
?application
iapp
są już paczkami (tzn. Masz już__init__.py
je obie). W wyniku dodając__init__.py
takżefolder
,application.app.folder
staje się (pod) pakiet , z którego można uzyskać dostęp do modułuapplication.app.folder.file
, którego symbolemfunc_name
mogą być teraz importowaneGdy moduły znajdują się w równoległych lokalizacjach, jak w pytaniu:
Ten skrót powoduje, że jeden moduł jest widoczny dla drugiego:
źródło
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
cli/foo.py
z linii poleceń był w stanieimport cli.bar
sys.path.append('.')
przeciwko importowaniu modułu za pomocąfrom app2.some_folder.some_file import your_function
. Alternatywnie to, co działa dla mnie, to uruchamianiepython3 -m app2.another_folder.another_file
z folderu głównego.Najpierw zaimportuj sys w name-file.py
Drugi dołączyć ścieżkę folderu w name-file.py
Po trzecie Stwórz pusty plik o nazwie __inicjat __.py w podkatalogu (to mówi Pythonowi, że jest to pakiet)
Po czwarte zaimportuj moduł do folderu w name-file.py
źródło
sys.path.insert
-command. W związku z tym odpowiedź pozostawia pytanie, czy to rozwiązanie działa nawet wtedy, gdy folder nazw znajduje się w dowolnej lokalizacji.Myślę, że ad-hoc może polegać na użyciu zmiennej środowiskowej,
PYTHONPATH
jak opisano w dokumentacji: Python2 , Python3źródło
Odpowiedzi tutaj są niejasne, jest to testowane na Pythonie 3.6
Dzięki tej strukturze folderów:
Gdzie
myfile.py
jest treść:Instrukcja importu w
main.py
:a to wydrukuje cześć .
źródło
__init__.py
?__init__.py
nie działa dla mnie. Używam Py 3.6.5 na Ubuntu 18. Działa na Pycharm, ale nie z terminalaProblem polega na tym, że Python szuka tego pliku w katalogu Python i go nie znajduje. Musisz określić, że mówisz o katalogu, w którym się znajdujesz, a nie o języku Python.
Aby to zrobić, zmień to:
from application.app.folder.file import func_name
do tego:
Dodając kropkę, mówisz, spójrz w tym folderze na folder aplikacji zamiast szukać w katalogu Python.
źródło
Z tego co wiem, dodaj
__init__.py
plik bezpośrednio w folderze funkcji, które chcesz zaimportować, wykona zadanie.źródło
sys.path.append(tools_dir)
na Windowsie i nie muszę dodawać__init__.py' file in my directory
katalogu tools_dir`W Pythonie 3.4 i nowszych wersjach można importować bezpośrednio z pliku źródłowego (link do dokumentacji) . To nie jest najprostsze rozwiązanie, ale dołączam tę odpowiedź dla kompletności.
Oto przykład. Najpierw plik do zaimportowania o nazwie
foo.py
:Kod, który importuje powyższy plik, w dużej mierze zainspirowany przykładem w dokumentacji:
Wyjście:
Zauważ, że nazwa zmiennej, nazwa modułu i nazwa pliku nie muszą być zgodne. Ten kod nadal działa:
Wyjście:
Programowe importowanie modułów zostało wprowadzone w Pythonie 3.1 i daje większą kontrolę nad sposobem importowania modułów. Więcej informacji znajduje się w dokumentacji.
źródło
Pracował dla mnie w python3 na Linuksie
źródło
sys.path.append("/home/linux/folder/")
- Upewnij się, że nie korzystasz ze skrótu, np."~/folder/"
Wypróbuj import względny Pythona:
Każda kropka wiodąca to kolejny wyższy poziom w hierarchii, rozpoczynający się od bieżącego katalogu.
Problemy? Jeśli to nie działa, prawdopodobnie masz problem z relatywnym importem wielu gotcha. Przeczytaj odpowiedzi i komentarze, aby uzyskać więcej informacji: Jak naprawić „Próba importu względnego w pakiecie innym”, nawet jeśli __init__.py
Wskazówka: mieć
__init__.py
na każdym poziomie katalogu. Możesz potrzebowaćpython -m application.app2.some_folder.some_file
(pomijając .py), który uruchamiasz z katalogu najwyższego poziomu lub masz ten katalog najwyższego poziomu w PYTHONPATH. Uff!źródło
Stoiłem przed tym samym wyzwaniem, zwłaszcza podczas importowania wielu plików, w ten sposób udało mi się go pokonać.
źródło
Biorąc pod uwagę,
application
jako głównego katalogu swojego projektu Pythona, utwórz pusty__init__.py
plikapplication
,app
ifolder
foldery. Następniesome_file.py
dokonaj zmian w następujący sposób, aby uzyskać definicję func_name:źródło
Użycie sys.path.append z bezwzględną ścieżką nie jest idealne przy przenoszeniu aplikacji do innych środowisk. Użycie ścieżki względnej nie zawsze będzie działać, ponieważ bieżący katalog roboczy zależy od sposobu wywołania skryptu.
Ponieważ struktura folderów aplikacji jest stała, możemy użyć os.path, aby uzyskać pełną ścieżkę modułu, który chcemy zaimportować. Na przykład, jeśli jest to struktura:
Powiedzmy, że chcesz zaimportować moduł „mango”. W vanilla.py możesz wykonać następujące czynności:
Oczywiście nie potrzebujesz zmiennej mango_dir.
Aby zrozumieć, jak to działa, spójrz na ten przykład sesji interaktywnej:
I sprawdź dokumentację os.path .
źródło
To działa dla mnie w systemie Windows
źródło
Jestem wyjątkowy: używam Pythona w systemie Windows!
Po prostu uzupełniam informacje: zarówno w systemie Windows, jak i Linux działają ścieżki względne i bezwzględne
sys.path
(potrzebuję ścieżek względnych, ponieważ używam skryptów na kilku komputerach i w różnych katalogach głównych).A kiedy zarówno w systemie Windows
\
i/
może być używany jako separator dla nazw plików i oczywiście trzeba podwoić\
do strun Pythonieniektórych ważnych przykładów:
(uwaga: myślę, że
/
jest to wygodniejsze niż\
zdarzenie, jeśli jest mniej „natywne dla systemu Windows”, ponieważ jest kompatybilne z Linuksem i łatwiejsze do pisania i kopiowania do Eksploratora Windows)źródło
Jeśli celem ładowania modułu z określonej ścieżki jest udzielenie pomocy podczas tworzenia modułu niestandardowego, można utworzyć łącze symboliczne w tym samym folderze skryptu testowego, który wskazuje na katalog główny modułu niestandardowego. To odwołanie do modułu będzie miało pierwszeństwo przed innymi modułami zainstalowanymi o tej samej nazwie dla dowolnego skryptu uruchomionego w tym folderze.
Testowałem to na Linuksie, ale powinno działać w każdym nowoczesnym systemie operacyjnym obsługującym łącza symboliczne.
Zaletą tego podejścia jest to, że możesz wskazać moduł, który siedzi we własnej kopii roboczej lokalnego oddziału SVC, co może znacznie uprościć czas cyklu programowania i zmniejszyć tryby awarii zarządzania różnymi wersjami modułu.
źródło
W moim przypadku miałem klasę do zaimportowania. Mój plik wyglądał tak:
W moim głównym pliku umieściłem kod poprzez:
źródło
Kilka razy wpadłem na to samo pytanie, więc chciałbym podzielić się moim rozwiązaniem.
Wersja Python: 3.X
Poniższe rozwiązanie jest przeznaczone dla osób, które opracowują aplikację w języku Python w wersji 3.X, ponieważ język Python 2 nie jest obsługiwany od 1 stycznia 2020 r .
Struktura projektu
W Pythonie 3 nie potrzebujesz
__init__.py
w podkatalogu projektu ze względu na pakiety Implicit Namespace . Zobacz Czy init .py nie jest wymagany dla pakietów w Python 3.3+Opis problemu
W
file_b.py
chciałbym zaimportować klasęA
wfile_a.py
folderze a.Rozwiązania
# 1 Szybki, ale brudny sposób
Bez instalowania pakietu, tak jak obecnie tworzysz nowy projekt
Za pomocą przycisku
try catch
sprawdź, czy błędy. Przykład kodu:# 2 Zainstaluj pakiet
Po zainstalowaniu aplikacji (w tym poście samouczek instalacji nie jest dołączony)
Możesz po prostu
Miłego kodowania!
źródło
Pracowałem nad projektem,
a
który chciałbym, aby użytkownicy zainstalowali zapip install a
pomocą następującej listy plików:setup.py
MANIFEST.in
a / init .py
a / a.py
a / b / init .py
a / b / b.py
Zainstalowałem moduł, uruchamiając następujące z katalogu z
MANIFEST.in
:Następnie z zupełnie innej lokalizacji w moim systemie plików
/moustache/armwrestle
mogłem uruchomić:Co potwierdziło, że
a.cats
rzeczywiście równa się 0 ia.b.dogs
rzeczywiście równa się 1, zgodnie z zamierzeniami.źródło
Zamiast po prostu
import ...
wykonaj:from <MySubFolder> import <MyFile>
MyFile znajduje się w MySubFolder.
źródło
Możesz odświeżyć powłokę Pythona, naciskając klawisz f5 lub przejdź do opcji Run-> Uruchom moduł. W ten sposób nie musisz zmieniać katalogu, aby odczytać coś z pliku. Python automatycznie zmieni katalog. Ale jeśli chcesz pracować z różnymi plikami z innego katalogu w Pythonie Shell, możesz zmienić katalog w sys, jak wcześniej powiedział Cameron .
źródło
Właśnie kliknąłem moje IDE prawym przyciskiem myszy i dodałem nowy
folder
i zastanawiałem się, dlaczego nie mogłem z niego importować. Później zrozumiałem, że muszę kliknąć prawym przyciskiem myszy i utworzyć pakiet Python, a nie klasyczny folder systemu plików. Lub metoda pośmiertna polegająca na dodaniu__init__.py
(co powoduje, że Python traktuje folder systemu plików jako pakiet), jak wspomniano w innych odpowiedziach. Dodając tutaj tę odpowiedź na wypadek, gdyby ktoś wybrał tę trasę.źródło
Możesz użyć importlib, aby zaimportować moduły, w których chcesz zaimportować moduł z folderu za pomocą łańcucha:
W tym przykładzie znajduje się main.py, który jest powyższym kodem, a następnie folder o nazwie Skrypty, a następnie można wywoływać z tego folderu, co jest potrzebne, zmieniając
scriptName
zmienną. Następnie możesz użyćscript
odniesienia do tego modułu. na przykład jeśli mam funkcję wywoływanąHello()
w module Snake, możesz uruchomić tę funkcję, wykonując to:Przetestowałem to w Pythonie 3.6
źródło
Miałem te problemy wiele razy. Często odwiedzam tę samą stronę. W moim ostatnim problemie musiałem uruchomić
server
ze stałego katalogu, ale za każdym razem, gdy debugowałem, chciałem uruchomić z różnych podkatalogów.zrobił NIE działa dla mnie, ponieważ w różnych modułach musiałem przeczytać inny * .csv plików, które były w tym samym katalogu.
W końcu to, co zadziałało, nie było pytoniczne, ale:
Użyłem
if __main__
na górze modułu, który chciałem debugować , który jest uruchamiany z innej niż zwykle ścieżki.Więc:
źródło