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.pyscript 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_apientraî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.pyserait *
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 myprojectutilisant pip. L'astuce consiste à utiliser le -edrapeau 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 installfonctionneront toujours correctement. Voir un exemple ci-dessous.
Testez la solution
Maintenant, testons la solution en utilisant api.pydéfinie ci-dessus et test_one.pydé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.pathhacks et de lire la seule solution réelle qui a été publiée jusqu'à présent (après 7 ans!).