Python: l'importation d'un sous‑ensemble ou d'un sous‑module de

Avoir déjà utiliser un colis, je ne m'attendais pas à la question que j'ai rencontré avec les packages imbriqués. Ici, c'est...

La disposition des répertoires

dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py

Contenu de init.py

Les deux package/__init__.py et package/subpackage/__init__.py sont vides.

Contenu de module.py

# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...

Contenu de test.py (3 versions)

Version 1

# file test.py
from package.subpackage.module import *
print attribute1 # OK

C'est le mauvais et dangereux d'importer des choses (importer le tout dans un encombrement), mais il fonctionne.

Version 2

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1

Un moyen plus sûr d'importation, article par article, mais il échoue, Python ne veux pas de cela: échoue avec le message: "Pas de module module". Cependant, ...

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here

... dit <module 'package.subpackage.module' from '...'>. Donc, c'est un module, mais ce n'est pas un module /-P 😯 ... euh

Version 3

# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK

Celui-ci fonctionne. Si vous êtes obligé d'utiliser le matraquage préfixe tout le temps ou de l'utilisation de l'insécurité façon que dans la version #1 et rejetée par Python à utiliser le coffre-fort moyen pratique? La meilleure façon de faire, qui est à l'abri et d'éviter d'inutiles long préfixe est le seul qui Python rejeter? Est-ce parce qu'il aime import * ou parce qu'il aime trop les préfixes (ce qui n'aide pas à appliquer cette pratique)?.

Désolé pour les mots durs, mais ça fait deux jours que j'essaie de travailler autour de cette stupide comme comportement. À moins que j'ai été totalement tort, quelque part, cela me laisse avec un sentiment que quelque chose est vraiment cassé dans Python, modèle de colis et sous‑packages.

Notes

  • Je ne veux pas compter sur sys.path, pour éviter mondiale effets secondaires, ni sur *.pth des fichiers, qui ne sont qu'une autre façon de jouer avec sys.path avec le même effets. Pour la solution la propreté, il doit être en local uniquement. Python est capable de gérer des sous-paquetage, soit il ne l'est pas, mais il ne devrait pas besoin de jouer avec la configuration globale pour être en mesure de traiter des matériaux locaux.
  • J'ai aussi essayé le recours aux importations dans package/subpackage/__init__.py, mais rien n'y faisait, il ne le même, et se plaint subpackage n'est pas un module, alors que print subpackage dit que c'est un module (comportement bizarre, encore une fois).

Je suis peut-être totalement faux dur (l'option que je préfère), mais cela m'a beaucoup déçu sur Python.

Tout autre moyen connu à côté des trois que j'ai essayé? Quelque chose que je ne le sais pas?

(soupir)

----- %< ----- edit ----- >% -----

Conclusion jusqu'à présent (d'après les commentaires des internautes)

Il n'y a rien comme de vrais sous‑ensemble de Python, comme toutes les références de paquet va à un mondial dictionnaire, seulement, il n'y a pas de dictionnaire, ce qui implique qu'il n'y a pas moyen de gérer le forfait local de référence.

Vous devez utiliser plein de préfixe ou de courte préfixe ou un alias. Comme dans:

Plein préfixe version

from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)

Court préfixe version (mais préfixe répétées)

from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

Ou d'autre, une variation de la ci-dessus.

from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context

Factorisée version

Si vous n'avez pas l'esprit à propos de l'importation de plusieurs entité à la fois dans un lot, vous pouvez:

from package.subpackage.module import attribute1, attribute2
# and etc.

Pas dans mon premier goût préféré (je préfère avoir une instruction d'importation par importées de l'entité), mais peut-être le seul, je vais personnellement faveur.

Mise à jour (2012-09-14):

Semble enfin s'être OK, dans la pratique, sauf avec un commentaire à propos de la mise en page. Au lieu de ce qui précède, j'ai utilisé:

from package.subpackage.module import (

    attribute1, 
    attribute2,
    attribute3,
    ...)  # and etc.
  • Comment vont les choses lorsque vous écrivez "de . le module d'importation" en "/package/subpackage/__init__.py"?
  • Votre "factorisée version" semble exactement à ce que vous voulez faire. Si vous effectuez une importation séparée de la ligne de attribut1 et attribut2 (comme vous "préférez"), vous êtes juste délibérément de vous donner plus de travail. Il n'y a pas de raison de le faire.
  • Désolé mais je ne comprends pas ce que vous voulez. Pourriez-vous reformuler votre question en plus de façon claire? Qu'aimeriez-vous faire exactement? Je veux dire, qu'aimeriez-vous écrire cela ne fonctionne pas et comment vous attendez-vous à travailler? Par ce que j'ai lu, je pense que vous ce que la sémantique de l'import comme Java ou peut-être que C est de les inclure. Dernière chose: vous pouvez faire un module "star-import" sécurité de l'ajout d'un __all__ variable qui contient une liste des noms qui doit être exportées quand un importés. edit: Bon, la lecture BrenBarn réponse que j'ai compris ce que tu voulais dire.
InformationsquelleAutor Hibou57 | 2012-09-01