Comment la référence au haut-niveau module en Python à l'intérieur d'un paquet?
Dans le dessous de la hiérarchie, est-il une pratique et de façon universelle de référence pour la top_package à l'aide d'un terme générique à tous .py fichier ci-dessous? Je voudrais avoir un moyen cohérent d'importer d'autres modules, de sorte que même lorsque le "top_package" change de nom rien ne casse.
Je ne suis pas en faveur de l'aide relative à l'importation comme "..level_one_a" que le chemin sera différent pour chaque fichier python ci-dessous. Je suis à la recherche d'une manière qui:
- Chaque fichier python peuvent avoir la même instruction import pour le même module dans le package.
- Un découplage référence à "top_package" en tout .py fichier à l'intérieur du paquet, donc quel que soit le nom de "top_package" transforme en, rien ne casse.
top_package/ __init__.py level_one_a/ __init__.py my_lib.py level_two/ __init__.py hello_world.py level_one_b/ __init__.py my_lib.py main.py
Pourquoi voulez-vous une référence vers le haut-niveau module? (Parfois, cette réponse révèle le vrai problème/solution).
Je veux faire de l'emballage réutilisables que possible, de sorte que lorsque j'ai renommer le module supérieur, tout peut encore fonctionner normalement, sans avoir à modifier chaque nom d'importation de l'intérieur.
Je veux faire de l'emballage réutilisables que possible, de sorte que lorsque j'ai renommer le module supérieur, tout peut encore fonctionner normalement, sans avoir à modifier chaque nom d'importation de l'intérieur.
OriginalL'auteur hllau | 2012-01-02
Vous devez vous connecter pour publier un commentaire.
Cela devrait faire l'affaire:
Le truc c'est que pour chaque module de la
__name__
variable contient le chemin complet vers le module séparés par des points tels que, par exemple,top_package.level_one_a.my_lib
. Donc, si vous voulez obtenir le package de haut nom, vous le besoin juste pour obtenir le premier composant du chemin d'accès et l'importer en utilisant__import__
.Malgré le nom de la variable utilisée pour accéder à l'emballage est toujours appelé
top_package
, vous pouvez renommer le paquet et si encore du travail.Merci pour votre commentaire. J'ai fixé ma réponse travailler quel que soit le top du nom du package.
Ce n'est pas tout à fait correcte; si le module n'est pas importé de haut niveau, son
__name__
ne contient le chemin d'accès complet à ce module, mais seulement une partie de ce qui va commencer à partir de l'endroit où vous importer ce module.OriginalL'auteur jcollado
Mettre votre paquet et le
main
script dans un conteneur externe répertoire, comme ceci:Quand
main.py
est exécuté, son répertoire parent (container
) sera automatiquement ajouté au début desys.path
. Et depuistop_package
est maintenant dans le même répertoire, il peut être importé à partir de n'importe où à l'intérieur de l'arbre.Donc
hello_world.py
pourrait importerlevel_one_b/my_lib.py
comme ceci:Quel que soit le nom du répertoire de conteneur est, où il est situé, les importations de travailler avec cet arrangement.
Mais note que, dans votre exemple,
top_package
il peut facilement fonctionner comme le dossier conteneur lui-même. Tout ce que vous avez à faire est de supprimertop_package/__init__.py
, et vous serez à gauche avec efectively le même arrangement.La précédente importation, déclaration de changer pour:
et vous seriez libre de renommer
top_package
toutefois vous l'avez souhaité.Nope - il fonctionnera parfaitement bien. Mais remarque que je faisais allusion à la structure de la Fpo question, pas à celui indiqué dans ma réponse. La différence essentielle est l'emplacement de la
main.py
script.La partie principale de votre réponse, je suis d'accord, mais le paragraphe qui commence par "Mais" est ce que je suis en désaccord avec. Si vous n'avez pas moyen de déplacer les deux level_one_a et level_one_b dans un nouveau sous-module de top_container.
Manifestement, vous n'avez pas fait les tests avec le code réel. Tout dans ma réponse fonctionne exactement comme indiqué. Je ne comprends pas ce que votre désaccord est basé sur.
Oui, j'ai. En fait, je suis juste allé à travers le processus douloureux de mettre en place un projet qui n'utilise pas de chemin munging pour la première fois. À la réflexion, cependant, les bibliothèques peuvent importer les uns des autres, s'ils sont importés par la main. Mais pas lorsqu'elle est invoquée à partir des programmes de test à l'intérieur de la level_one modules, même si les programmes de test sont invoquées par les "découvrir" mécanisme. Votre idée pour un haut niveau de package de wrapper est ce que finalement résolu mon assortiment de problèmes d'importation (j'ai été exigeant main/tests/peluches pour tous les travaux).
OriginalL'auteur ekhumoro
Vous pouvez utiliser une combinaison de la
__import__()
de la fonction et de la__chemin__
attribut d'un paquet.Par exemple, supposons que vous souhaitez importer
<whatever>.level_one_a.level_two.hello_world
de quelque part d'autre dans le paquet. Vous pourriez faire quelque chose comme ceci:Ce code est indépendant du nom de haut niveau, et peut être utilisé n'importe où dans le package. Il est également assez laid.
OriginalL'auteur srgerg
Je crois #2 est impossible sans l'aide relative des importations ou le paquet nommé. Vous devez spécifier ce module pour importer en appelant explicitement à son nom ou à l'aide d'un parent à l'importation. sinon, comment serait l'interprète savez ce que vous voulez?
Si vous faites votre demande de lanceur d'un niveau au-dessus
top_level/
et l'ontimport top_leve
l vous pouvez ensuite faire référencetop_level.*
à partir de n'importe où à l'intérieur de la top_level paquet.(Je peux vous montrer un exemple de logiciel, je suis à travailler sur: http://github.com/toddself/beerlog/)
OriginalL'auteur tkone
Cela fonctionne à partir de l'intérieur d'un module de la bibliothèque:
OriginalL'auteur Apalala