6
votes

Python: Comment puis-je choisir quel module à importer quand ils sont nommés le même

permet de dire que je suis dans un fichier appelé op3Id.py et je le fais: xxx

J'ai le module op3 / code> Mon PythonPath mais l'interprète semble essayer d'utiliser mon fichier op3Id.py . Comment puis-je obtenir la version de la bibliothèque?

(Bien sûr, autre chose que la réponse «renommée de votre fichier» évidente serait bien).


5 commentaires

'Renommez votre fichier'


Quelle est la raison de ne pas renommer le fichier? Cela semble être une petite solution par rapport à la recherche d'un moyen autour de lui.


Le fichier doit être appelé sémantiquement OpenID, car il se trouve dans un module avec des "types" d'alias. OpenID est le nom du type.


Ces modules sont-ils situés dans le module parent alias ?


Oui, ils sont tous. Mais à l'intérieur du fichier "openid.py", je ne peux pas sembler avoir accès à la bibliothèque "OpenID". C'est le problème principal.


5 Réponses :


3
votes

renommez-le . C'est l'idée derrière les espaces de noms. Votre OpenID pourrait être un sous-module dans votre module supérieur Projet . Votre adresse e-mail sera heurté avec le module supérieur email dans stdlib.

Parce que votre OpenID n'est pas universel, il fournit un cas particulier pour votre projet.


3 commentaires

En fait, je pense que l'idée des espaces de noms est pas de devoir le renommer à quelque chose d'unique;) myProject.opénide est quelque chose de différent que OpenID. Avec les nouvelles importations absolues, Import OpenID obtiendra toujours le module à l'échelle du système (E.G. STDLIB) et que le relativement .OpenID obtiendra la sous-sotilisation OpenID dans le module actuel.


Bien sûr que ce n'est pas le cas. Si il son module Project qu'il devait utiliser projet.opénide . Ce n'est pas clair pourquoi OP fait ce qu'il fait, mais s'il n'a pas de module projet , il devrait renommer OpenID à autre chose.


correct. En dehors du paquet, c'est pkg.opénide. Mais à l'intérieur du fichier "openid.py", je ne peux pas avoir accès à la bibliothèque "OpenID". C'est le problème principal.



1
votes

Vous pouvez utiliser des importations relatives ou absolues (selon les spécificités de votre situation), qui sont couvertes dans PEP 328 Plus récemment. Bien sûr, sérieusement, vous ne devriez pas créer de conflits de nommage comme celui-ci et devriez renommer votre fichier.


4 commentaires

Même si le nom sémantiquement correct pour le fichier est OpenID? Comme si c'est dans un répertoire de types d'alias avec, e-mail, page Web, domaine, etc.?


@Paul: Même alors. Si c'est dans un "répertoire des types d'alias", cela devrait être un paquet, puis c'est pkg.opénide, qui est sans ambiguïté.


correct. En dehors du paquet, c'est pkg.opénide. Mais à l'intérieur du fichier "openid.py", je ne peux pas avoir accès à la bibliothèque "OpenID". C'est le problème principal.


@Paul: Bien sûr de pouvoir. Utilisez une importation absolue (de Future Importer absolute_import) et «importez OpenID», ce qui résoudra en tant que (structure pseudo-path-structure) / OpenID, au lieu de / PKG / OpenID.



9
votes

C'est la raison pour laquelle les importations absolues ont été choisies comme nouveau comportement par défaut. Cependant, ils ne sont pas encore la valeur par défaut en 2.6 (peut-être en 2.7 ...). Vous pouvez obtenir leur comportement maintenant en les importatant à partir du futur:

from __future__ import absolute_import


0 commentaires

-1
votes

Vous pouvez essayer de mélanger sys.path , pour déplacer les répertoires intéressants vers le front avant de faire l'importation.


3 commentaires

Ne vous aidera pas si sys.modules ['OpenID'] est déjà défini, car il serait dans le cas de l'OP car il est dans OpenID.py .


@ALEX Pourquoi ce serait-il le cas? Le fichier actuel est-il automatiquement ajouté à SyS.Modules? Un test rapide.py <"Importerys sys; imprimer sys.modules.keys ()", quand exécuter, suggère autrement !?


Un module importé est ajouté à Sys.Modules sous son nom réel; Le fichier unique qui est exécuté en tant que "Programme principal" obtient le nom classique de __ principal __ à la place. Mais si vous exécutez que OpenID.py comme module principal, il n'y a aucune raison de l'avoir sur Sys.Path en premier lieu!



2
votes

Je ne vais pas entrer dans les polémiques sur le renommage et je me concentrerai plutôt sur vous montrer comment faire ce que vous voulez (que ce soit "bon pour toi" ou non ;-). La solution n'est pas difficile ...

Il suffit de définir __ chemin __ code>! Une petite démonstration: p> xxx pré>

ceci montre un module em> OpenID Gestion pour importer un paquet em> homonyme em> même si le chemin du module vient Plus tôt dans Sys.Path, et strong> sys.modules ['OpenID'] code> est clairement déjà défini à ce moment-là. Et tout le "secret" est dans openid.py code simple de ...: p> xxx pré>

sans le chemin __ __ code> attribution, bien sûr, il serait seulement EMIT module! code>. p>

fonctionne également pour importer des sous-modules dans l'emballage, bien sûr. FAIRE: P>

$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid'
Module!
Package!
Submod!
$ 


5 commentaires

Concernant Sys.Modules ['OpenID'] étant défini. Vous avez également dit cela dans un autre commentaire, mais je ne suis pas si sûr. Pourquoi ce serait-il le cas? Le fichier actuel est-il automatiquement ajouté à SyS.Modules? Un test rapide.py <"impression sys; imprimer" test "dans sys.modules.keys ()", quand exécuter, suggère autrement !?


Comme je me suis répondu à l'autre commentaire: le fichier qui est exécuté car le module principal passe dans sys.modules ['__ Main __'] à la place (comme son __ nom __ est artificiellement et classiquement. Définissez sur __ Main __ ). C'est pourquoi je suis importer ing OpenID ici, pour montrer que __ chemin __ fonctionne toujours. Si tout ce que vous avez besoin avec OpenID.py est de l'exécuter comme principal, il n'y a aucune raison de l'avoir dans Sys.Path.


Je pensais que le problème de l'OP découle simplement du fait que "". Vient plus tôt dans Sys.Path, le répertoire actuel est donc recherché sur "OpenID" où l'importateur OpenID.py Script est recherché. Mais si vous déplacez les répertoires «intéressants» de Sys.Path à son avant, l'autre «OpenID» (le module) se trouve en premier et tout va bien.


C'est extrêmement déroutant (vous et les op et les deux apparaissent tous les deux semblent faire cela parfois) pour se référer au Package OpenID comme "le module" - op3Id.py est le module, répertoire OpenID avec un fichier __init __. py est le paquet. Si openid.py n'est jamais importé, alors piratage Sys.Path travaille; Cependant, ma réponse fonctionne plus généralement (si OpenID.py est importée ou exécutée comme script principal), et évite de jouer avec les paramètres système-global.


Merci, je l'ai eu. Je vais aussi essayer d'améliorer mon libellé :-).