Vous avez presque tout ce dont vous avez besoin (même un peu plus)! J'irais avec la configuration suivante:
code.py:
foo = 1
__init__.py:
from .code import foo
Faire un par rapport à l'importation ici, car __init__.py
sera utilisé lors de l'importation de l'ensemble du paquet. Notez que nous marquer explicitement les importer en tant que parent par l'aide de la .
-syntaxe, car cela est nécessaire pour Python 3 (et en Python 2 si vous n'avez from __future__ import absolute_import
).
__main__.py:
from Package import foo
print('foo = ', foo)
C'est le script principal, et nous utilisons donc une absolue import
déclaration. Ce faisant, nous supposons que le paquet a été installé (ou au moins a été mis sur le chemin); et c'est la façon dont les paquets doivent être traitées avec! Vous pourriez penser que cela est en conflit avec votre troisième cas d'utilisation, mais en fait il n'y a pas de raison de pas à pip install
face à un package. Et il n'est vraiment pas une grosse affaire (en particulier lors de l'utilisation d'un virtualenv
)!
Si votre préoccupation est de bricoler avec les fichiers source et facilement observer les changements par rapport à l'exécution de l' __main__.py
le fichier, alors vous pouvez simplement installer le paquet à l'aide de l' -e
("modifiable") commutateur: pip install -e .
(en supposant que vous êtes dans le répertoire Package
). Avec votre structure de répertoire en cours, cependant, cela ne fonctionne pas parce que l' -e
switch place un egg-link
dans le répertoire contenant l' setup.py
le dossier; ce répertoire ne contient pas de paquetage nommé Package
mais src
à la place (j'ai une question à ce sujet).
Au lieu de cela, si vous suivez la convention pour nommer le répertoire racine d'une source du paquet après que le paquet lui-même (c'est - Package
de votre exemple) puis de l'installation avec des -e
n'est pas un problème: Python n'trouver le package requis Package
dans le répertoire correspondant:
$ tree Package/
Package/
├── setup.py
└── Package <-- Renamed "src" to "Package" because that's the package's name.
├── code.py
├── __init__.py
└── __main__.py
Ceci vous permet également d'omettre la meilleure définition de l' package_dir={'Package': 'src'}
en setup.py
.
Une remarque à propos de setup.py
: Pour les trois cas d'utilisation qui vous avez spécifié, il n'est pas nécessaire de définir un point d'entrée. C'est que vous pouvez sauter la ligne entry_points={ 'console_scripts': ['Package = src.__main__:main' ] }
. Par l'envoi d'un __main__.py
module python -m Package
sera facilement exécuter du code dans ce module. Vous pouvez également ajouter un supplémentaire si la clause:
def main():
print('foo = ', foo)
if __name__ == '__main__':
main()
Le point d'entrée sur l'autre main vous permet d'exécuter directement le code en __main__.main
de la CLI; qui est en cours d'exécution $ Package
va exécuter le code correspondant.
Recap
La ligne de fond est que je serais toujours utiliser pip install
lorsqu'ils traitent avec des paquets. Et pourquoi pas, surtout si vous avez déjà créé un setup.py
le fichier? Si des modifications de l'emballage doivent être appliqués "en temps réel", alors vous pouvez l'installer avec l' -e
de l'interrupteur (ce qui peut nécessiter un changement de nom de l' src
le dossier, voir ci-dessus). Donc votre troisième cas d'utilisation se lire comme "Télécharger la source et l' pip install (-e) Package
(dans un virtualenv); ensuite, vous pouvez exécuter python __main__.py
".
Modifier
Exécutez __main__.py
sans pip install
Si vous ne souhaitez pas installer le paquet via pip, mais encore être en mesure d'exécuter l' __main__.py
script, j'avais toujours aller avec la configuration ci-dessus. Ensuite, nous devons faire en sorte que l' from Package import ...
déclaration(s) sont toujours réussir et cela peut être réalisé par l'extension du chemin d'importation (à noter que cela nécessite l' src
annuaire être renommé le nom du paquet!).
Modifier PYTHONPATH
Pour Linux, bash, vous pouvez définir le Pythonpath comme suit:
export PYTHONPATH=$PYTHONPATH:/path/to/Package
Ou si vous êtes dans le même répertoire que __main__.py
:
export PYTHONPATH=$PYTHONPATH:`cd ..; pwd`
Bien sûr, il existe différentes manières pour différents systèmes d'exploitation.
Étendre le chemin de __main__.py
Vous (ou plutôt votre collègue) pourrait ajouter les lignes suivantes en haut du script (avant l' from Package import ...
des déclarations):
import sys
sys.path.append('/path/to/Package')
Étendre le chemin de sitecustomize.py
Vous pouvez placer un module nommé sitecustomize.py
dans la lib/python3.5/site-packages/
répertoire de votre installation de Python qui contient les lignes suivantes:
import sys
sys.path.append('/path/to/Package')
La création d'un haut niveau, main.py
script
Donc, si vous voulez avoir la présentation suivante:
$ tree Package/
Package/
├── main.py <-- Add this file.
├── setup.py
└── src
├── code.py
├── __init__.py
└── __main__.py
où main.py
contient
import src.__main__
Maintenant, __main__.py
est traitée comme une partie de l' src
paquet et le rapport de l'importation travail.
Au lieu de courir python src/__main__.py
vous exécutez python main.py
maintenant.