Masz dość hacków sys.path?
Dostępnych jest wiele sys.path.append
hacków, ale znalazłem alternatywny sposób rozwiązania problemu.
Podsumowanie
- Zawiń kod w jeden folder (np.
packaged_stuff
)
- Użyj opcji Utwórz
setup.py
skryptu którym używasz setuptools.setup () .
- Pip zainstaluj pakiet w stanie edytowalnym za pomocą
pip install -e <myproject_folder>
- Importuj za pomocą
from packaged_stuff.modulename import function_name
Ustawiać
Punktem wyjścia jest podana przez Ciebie struktura plików, zawinięta w folder o nazwie myproject
.
.
└── myproject
├── api
│ ├── api_key.py
│ ├── api.py
│ └── __init__.py
├── examples
│ ├── example_one.py
│ ├── example_two.py
│ └── __init__.py
├── LICENCE.md
├── README.md
└── tests
├── __init__.py
└── test_one.py
Zadzwonię do .
folderu korzenia, aw moim przykładowym przypadku to znajduje się C:\tmp\test_imports\
.
api.py
Jako przypadek testowy użyjmy następującego pliku ./api/api.py
def function_from_api():
return 'I am the return value from api.api!'
test_one.py
from api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
Spróbuj uruchomić test_one:
PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
File ".\myproject\tests\test_one.py", line 1, in <module>
from api.api import function_from_api
ModuleNotFoundError: No module named 'api'
Próbowanie importu względnego również nie zadziała:
Używanie from ..api.api import function_from_api
spowoduje
PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
File ".\tests\test_one.py", line 1, in <module>
from ..api.api import function_from_api
ValueError: attempted relative import beyond top-level package
Kroki
- Utwórz plik setup.py w katalogu głównym
Zawartość setup.py
będzie *
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
- Użyj środowiska wirtualnego
Jeśli znasz środowiska wirtualne, aktywuj jedno i przejdź do następnego kroku. Korzystanie ze środowisk wirtualnych nie jest absolutnie wymagane, ale naprawdę pomoże ci w dłuższej perspektywie (jeśli masz więcej niż jeden projekt w toku ..). Najbardziej podstawowe kroki to (uruchom w folderze głównym)
- Utwórz wirtualne środowisko
- Aktywuj środowisko wirtualne
source ./venv/bin/activate
(Linux, macOS) lub ./venv/Scripts/activate
(Win)
Aby dowiedzieć się więcej na ten temat, po prostu wypróbuj Google „samouczek wirtualnego środowiska python” lub podobny. Prawdopodobnie nigdy nie potrzebujesz żadnych innych poleceń niż tworzenie, aktywowanie i dezaktywowanie.
Po utworzeniu i aktywacji środowiska wirtualnego konsola powinna podać nazwę środowiska wirtualnego w nawiasie
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
a twoje drzewo folderów powinno wyglądać tak **
.
├── myproject
│ ├── api
│ │ ├── api_key.py
│ │ ├── api.py
│ │ └── __init__.py
│ ├── examples
│ │ ├── example_one.py
│ │ ├── example_two.py
│ │ └── __init__.py
│ ├── LICENCE.md
│ ├── README.md
│ └── tests
│ ├── __init__.py
│ └── test_one.py
├── setup.py
└── venv
├── Include
├── Lib
├── pyvenv.cfg
└── Scripts [87 entries exceeds filelimit, not opening dir]
- pip zainstaluj swój projekt w stanie edytowalnym
Zainstaluj pakiet najwyższego poziomu myproject
za pomocą pip
. Sztuką jest użycie -e
flagi podczas instalacji. W ten sposób jest on instalowany w stanie edytowalnym, a wszystkie zmiany dokonane w plikach .py zostaną automatycznie uwzględnione w zainstalowanym pakiecie.
W katalogu głównym uruchom
pip install -e .
(zwróć uwagę na kropkę, oznacza „bieżący katalog”)
Możesz również zobaczyć, że jest on instalowany przy użyciu pip freeze
(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0
- Dodaj
myproject.
do importu
Pamiętaj, że będziesz musiał dodać myproject.
tylko do importu, który inaczej nie działałby. Importowanie, które działało bez setup.py
& pip install
nadal będzie działać. Zobacz przykład poniżej.
Przetestuj rozwiązanie
Teraz przetestujmy rozwiązanie przy użyciu api.py
zdefiniowanych powyżej i test_one.py
zdefiniowanych poniżej.
test_one.py
from myproject.api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
uruchomienie testu
(venv) PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
I am the return value from api.api!
* Zobacz pełne dokumenty setuptools, aby uzyskać bardziej szczegółowe przykłady setup.py.
** W rzeczywistości środowisko wirtualne można umieścić w dowolnym miejscu na dysku twardym.
sys.path
hacki i przeczytać jedyne aktualne rozwiązanie, które zostało opublikowane (po 7 latach!).