web-dev-qa-db-fra.com

AttributeError: l'objet 'module' n'a pas d'attribut

J'ai deux modules python:

a.py

import b

def hello():
  print "hello"

print "a.py"
print hello()
print b.hi()

b.py

import a

def hi():
  print "hi"

Quand je lance a.py, je reçois:

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

Qu'est-ce que l'erreur signifie? Comment je le répare?

150
Stephen Hsu

Vous avez des importations mutuelles de premier niveau, ce qui est presque toujours une mauvaise idée.

Si vous devez vraiment avoir des importations mutuelles en Python, vous devez les importer dans une fonction:

# In b.py:
def cause_a_to_do_something():
    import a
    a.do_something()

Maintenant, a.py peut faire import b en toute sécurité sans causer de problèmes.

(À première vue, il pourrait sembler que cause_a_to_do_something() serait extrêmement inefficace, car il effectue une import à chaque fois que vous l'appelez, mais en réalité, le travail d'importation ne se fait que la première fois. opération.)

157
RichieHindle

J'ai également constaté cette erreur en nommant par inadvertance un module portant le même nom que l'un des modules Python standard. Par exemple. J'ai eu un module appelé commands qui est également un module de bibliothèque Python. Cela s'est avéré difficile à localiser car cela fonctionnait correctement dans mon environnement de développement local, mais échouait avec l'erreur spécifiée lors de l'exécution sur Google App Engine.

74
lucrussell

Le problème est la dépendance circulaire entre les modules. a imports b et b imports a. Mais l'un d'eux doit être chargé en premier - dans ce cas, python initialise le module a avant b et b.hi() n'existe pas encore lorsque vous essayez d'y accéder dans a.

39
sth

J'ai eu cette erreur en référençant une énumération qui avait été importée de manière incorrecte, par exemple

from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member

Importation correcte:

from package.MyEnumClass import MyEnumClass

J'espère que ça aide quelqu'un

16
Stoyan

J'ai rencontré cette erreur car le module n'a pas été réellement importé. Le code ressemblait à ceci:

import a.b, a.c

# ...

something(a.b)
something(a.c)
something(a.d)  # My addition, which failed.

La dernière ligne a pour résultat AttributeError. La cause était que je n'avais pas remarqué que les sous-modules de a (a.b et a.c) étaient explicitement importés et supposais que l'instruction import était réellement importée a.

7
Dag Høidahl

J'ai rencontré ce problème lorsque j'ai extrait une ancienne version d'un référentiel de git. Git a remplacé mes fichiers .py, mais a laissé les fichiers .pyc non suivis. Étant donné que les fichiers .py et les fichiers .pyc n'étaient pas synchronisés, la commande import dans un fichier .py n'a pas pu trouver le module correspondant dans les fichiers .pyc.

La solution consistait simplement à supprimer les fichiers .pyc et à les laisser être régénérés automatiquement.

3
craq

J'ai fait face au même problème. fixé en utilisant reload.

import the_module_name
from importlib import reload
reload(the_module_name)
2
Jiu

Toutes les réponses ci-dessus sont excellentes, mais j'aimerais commenter ici. Si vous n'avez repéré aucun des problèmes mentionnés ci-dessus, essayez de clarifier votre environnement de travail. Cela a fonctionné pour moi.

2
Jian

sur buntu 18.04 ( virtualenv , python.3.6.x ), la suivante recharger extrait résol le problème pour moi:

main.py

import my_module  # my_modyle.py
from importlib import reload # reload 
reload(my_module)

print(my_module)
print(my_modeule.hello())

où:

|--main.py    
|--my_module.py

pour plus documentation vérifier: ici

0
Behzad Sezar

Les importations circulaires posent des problèmes, mais Python dispose de moyens pour les atténuer.

Le problème est que lorsque vous exécutez python a.py, il exécute a.py mais ne le marque pas comme importé en tant que module. Donc, à son tour, a.py -> module d'importation b -> module d'importation a -> module d'importation b. La dernière importation est non-op depuis que b est en cours d'importation et Python s'en protège. Et b est un module vide pour l'instant. Ainsi, lorsqu'il exécute b.hi(), il ne trouve rien.

Notez que la b.hi() qui a été exécutée est pendant a.py -> module b -> module a, pas directement dans a.py.

Dans votre exemple spécifique, vous pouvez simplement exécuter python -c 'import a' au niveau supérieur, de sorte que la première exécution de a.py est enregistrée en tant qu'importation d'un module.

0
Hot.PxL

@ MD5 Idem pour moi, essayez de changer le nom du module ou d'importer directement la fonction

0
Patrick

Je ne sais pas comment mais le changement ci-dessous a réglé mon problème:

j'avais le nom du fichier et le même nom d'importation, par exemple, j'avais le nom de fichier emoji.py et j'essayais d'importer emoji. Mais changer le nom du fichier a résolu le problème.

J'espère que ça aide

0
MD5