Fatigué des hacks sys.path?
Il existe de nombreux sys.path.append
-hacks disponibles, mais j'ai trouvé un autre moyen de résoudre le problème en cours.
Sommaire
- Enveloppez le code dans un dossier (par exemple
packaged_stuff
)
- Utilisez create
setup.py
script où vous utilisez setuptools.setup () .
- Pip installe le package à l'état modifiable avec
pip install -e <myproject_folder>
- Importer avec
from packaged_stuff.modulename import function_name
Installer
Le point de départ est la structure de fichiers que vous avez fournie, enveloppée dans un dossier appelé 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
J'appellerai le .
dossier racine, et dans mon exemple, il se trouve à C:\tmp\test_imports\
.
api.py
Comme cas de test, utilisons ce qui suit ./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()
Essayez d'exécuter 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'
Essayer également les importations relatives ne fonctionnera pas:
L'utilisation from ..api.api import function_from_api
entraînerait
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
Pas
- Créez un fichier setup.py dans le répertoire racine
Le contenu du setup.py
serait *
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
- Utilisez un environnement virtuel
Si vous êtes familiarisé avec les environnements virtuels, activez-en un et passez à l'étape suivante. L'utilisation d'environnements virtuels n'est pas absolument nécessaire, mais ils vous aideront vraiment à long terme (lorsque vous avez plus d'un projet en cours ..). Les étapes les plus élémentaires sont (exécutées dans le dossier racine)
- Créer un environnement virtuel
- Activer l'environnement virtuel
source ./venv/bin/activate
(Linux, macOS) ou ./venv/Scripts/activate
(Win)
Pour en savoir plus à ce sujet, il suffit de rechercher sur Google "tutoriel d'environnement virtuel python" ou similaire. Vous n'avez probablement jamais besoin d'autres commandes que la création, l'activation et la désactivation.
Une fois que vous avez créé et activé un environnement virtuel, votre console doit donner le nom de l'environnement virtuel entre parenthèses
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
et votre arborescence de dossiers devrait ressembler à ceci **
.
├── 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 installez votre projet dans un état modifiable
Installez votre package de niveau supérieur en myproject
utilisant pip
. L'astuce consiste à utiliser le -e
drapeau lors de l'installation. De cette façon, il est installé dans un état modifiable et toutes les modifications apportées aux fichiers .py seront automatiquement incluses dans le package installé.
Dans le répertoire racine, exécutez
pip install -e .
(notez le point, il signifie "répertoire courant")
Vous pouvez également voir qu'il est installé en utilisant 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
- Ajoutez
myproject.
à vos importations
Notez que vous devrez ajouter myproject.
uniquement dans les importations qui ne fonctionneraient pas autrement. Les importations qui ont fonctionné sans le setup.py
& pip install
fonctionneront toujours correctement. Voir un exemple ci-dessous.
Testez la solution
Maintenant, testons la solution en utilisant api.py
définie ci-dessus et test_one.py
définie ci-dessous.
test_one.py
from myproject.api.api import function_from_api
def test_function():
print(function_from_api())
if __name__ == '__main__':
test_function()
exécuter le test
(venv) PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
I am the return value from api.api!
* Voir la documentation de setuptools pour des exemples plus détaillés de setup.py.
** En réalité, vous pouvez placer votre environnement virtuel n'importe où sur votre disque dur.
sys.path
hacks et de lire la seule solution réelle qui a été publiée jusqu'à présent (après 7 ans!).