2009-12-27 10 views
1

Dans mon répertoire python de travail je crée:Pourquoi je ne peux pas appeler packagename.modulename.foo()?

packagename/__init__.py 
packagename/modulename.py 
test.py 

En modulename.py je crée une classe vide:

class Someclass(object): 
    pass 

dans test.py:

import packagename 
packagename.modulename.Someclass() 

Pourquoi je peux » t appelez packagename.modulename.someclass() dans test.py?

AttributeError: 'module' object has no attribute 'modulename' 

Je comprends que le droit chemin est:

import packagename.modulename 

ou

from packagename import modulename 

Mais je ne comprends pas pourquoi je reçois cette erreur dans mon cas.

Mise à jour:

En d'autres termes, est-il possible d'importer le contenu d'un paquet avec tous les modules dans l'espace de noms distincts? J'ai besoin expression correcte pythonique pour:

from packagename import * as mynamespace 

Répondre

1

Si vous aviez 100 modules dans le package "packagename", souhaitez-vous qu'ils soient tous importés automatiquement lorsque vous avez importé uniquement le nom de niveau supérieur? Ce n'est généralement pas une bonne idée, donc Python ne le fait pas.

Si vous voulez avoir ce module particulier importé automatiquement, il suffit d'inclure dans le __init__.py comme ceci:

from packagename import modulename 

Alternativement, en utilisant Python 2.5 ou 2.6:

from __future__ import absolute_import 
from . import modulename 

(Dans les versions ultérieures , vous pouvez abandonner la pièce from __future__.)

Modifier: il n'y a pas mécanisme intégré pour demander à Python d'importer tous les sous-modules possibles dans un paquet. Ce n'est pas un cas d'utilisation courant, et il vaut mieux le traiter explicitement en ayant votre __init__.py importer exactement les choses que vous voulez. Il serait possible de mettre quelque chose ensemble pour faire le travail (en utilisant __import__() et autres) mais il est préférable dans la plupart des cas d'importer explicitement tous les sous-modules comme décrit.

+0

J'ai besoin de lister les modules de tous les paquets dans le fichier nomdupaquet/__ init_.py, n'est-ce pas? Je pense que j'ai besoin d'une expression python correcte pour "from packagename import * as mynamespace". – Alex

+0

Je pense que ça s'écrit simplement 'importer le nom du paquet sous monnamespace'. –

0

Certains paquets sont très grandes et tout importer en eux prendraient beaucoup de temps. Il est préférable d'offrir une granularité fine pour les importations, de sorte que l'utilisateur importe uniquement ce dont il a vraiment besoin.

2

Python ne recurise pas et n'imprime pas automatiquement les sous-packages. Quand vous dites:

import packagename 

C'est tout ce qu'il importe.Si vous dites:

import packagename.modulename 

Ensuite, il packagename premières importations, les importations et puis packagename.modulenameassignes une référence à elle comme un attribut de packagename. Par conséquent, quand vous dites dans le code:

packagename.modulename.Someclass() 

Python est juste en utilisant 100% normal d'attributs lookups. Recherchez d'abord la variable packagename dans l'espace de noms actuel. Recherchez ensuite l'attribut modulename de l'objet packagename. Recherchez ensuite l'attribut Someclass de l'objet modulename.

Si vous avez oublié d'importer packagename.modulename, alors il est clairement aucun attribut sur packagename appelé modulename, et désormais le AttributeError.

Je vous suggère d'ouvrir la ligne de commande et d'importer quelque chose, puis d'utiliser dir() pour l'examiner. Importez ensuite un sous-paquet et utilisez à nouveau dir(). Vous verrez rapidement la différence.


Enfin, la syntaxe:

from packagename.modulename import SomePackage 

est essentiellement la même que celle-ci:

import packagename.modulename 
SomePackage = packagename.modulename.SomePackage 

(bien sûr, il est mis en œuvre différemment, mais plus ou moins le même résultat).

Cela aide-t-il?

+0

@gahooa: Merci pour votre réponse, mais est-il possible d'importer tous les modules du paquet dans un espace de noms séparé? Quelque chose comme "import packagename. *" – Alex

Questions connexes