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

203

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 cours a.py, j'obtiens:

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

Que signifie l'erreur? Comment je le répare?

Stephen Hsu
la source
Notez que vos questions sont très similaires à cette réponse. Apparemment, le code de cette réponse fonctionne simplement trouver, mais le vôtre ne fonctionne pas? stackoverflow.com/a/7336880/565879
Buttons840

Réponses:

198

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, la façon de le faire est de les importer dans une fonction:

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

Désormais, a.py peut se passer de import bproblèmes en toute sécurité .

(À première vue, il peut sembler que ce cause_a_to_do_something()serait extrêmement inefficace car il effectue un importchaque fois que vous l'appelez, mais en fait, le travail d'importation n'est effectué que la première fois. La deuxième fois et les suivantes, vous importez un module, c'est une opération rapide. )

RichieHindle
la source
99

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

lucratif
la source
42

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

qc
la source
22

J'ai eu cette erreur en référençant une énumération qui a été importée d'une mauvaise manière, 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

Stoyan
la source
8

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

import the_module_name
from importlib import reload
reload(the_module_name)
Juste nous
la source
Cela m'a été utile - merci.
Tal Galili
7

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 abouti à un AttributeError. La cause était que je n'avais pas remarqué que les sous-modules de a( a.bet a.c) étaient explicitement importés et que j'avais supposé que l' importinstruction était effectivement importée a.

Dag Høidahl
la source
5

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

La solution était simplement de supprimer les .pycfichiers et de les laisser se régénérer automatiquement.

craq
la source
Vous pouvez utiliser cette commande pour supprimer tous les .pycfichiers:find . -name "*.pyc" -exec rm -f {} \;
Ollie
5

sur ubuntu 18.04 ( virtualenv , python.3.6.x ), l' extrait de rechargement suivant a résolu le problème pour moi:

main.py

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

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

où:

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

pour plus de documentation, consultez: ici

Behzad Sezari
la source
3

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

Jian
la source
0

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

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

J'espère que ça aide

MD5
la source
0

Les importations circulaires posent des problèmes, mais Python a des moyens de les atténuer intégrés.

Le problème est que lorsque vous exécutez python a.py, il s'exécute a.pymais ne le marque pas comme un module. Donc à son tour a.py-> importe le module b -> importe le module a -> importe le module b. La dernière importation est un no-op depuis que b est en cours d'importation et Python se protège contre cela. Et b est un module vide pour le moment. Alors quand il s'exécuteb.hi() , il ne trouve rien.

Notez que le b.hi()qui a été exécuté est pendant a.py-> module b -> module a, pas a.pydirectement.

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.pyest enregistrée comme importation d'un module.

Hot.PxL
la source
0

L' ordre de l'importation était la raison pour laquelle j'avais des problèmes:

a.py:

############
# this is a problem
# move this to below
#############
from b import NewThing

class ProblemThing(object):
    pass

class A(object):
   ###############
   # add it here
   # from b import NewThing
   ###############
   nt = NewThing()
   pass

b.py:

from a import ProblemThing

class NewThing(ProblemThing):
    pass

Juste un autre exemple de ce à quoi cela pourrait ressembler, similaire à la réponse de RichieHindie, mais avec des classes.

Jmunsch
la source
0

J'ai croisé ce problème à plusieurs reprises, mais je n'ai pas essayé de creuser plus profondément à ce sujet. Maintenant, je comprends le problème principal.

Cette fois, mon problème importait des sérialiseurs (django et restframework) à partir de différents modules tels que les suivants:

from rest_framework import serializers

from common import serializers as srlz
from prices import models as mdlpri

# the line below was the problem 'srlzprod'
from products import serializers as srlzprod

J'avais un problème comme celui-ci:

from product import serializers as srlzprod
ModuleNotFoundError: No module named 'product'

Ce que je voulais accomplir était le suivant:

class CampaignsProductsSerializers(srlz.DynamicFieldsModelSerializer):
    bank_name = serializers.CharField(trim_whitespace=True,)
    coupon_type = serializers.SerializerMethodField()
    promotion_description = serializers.SerializerMethodField()

    # the nested relation of the line below
    product = srlzprod.ProductsSerializers(fields=['id','name',],read_only=True,)

Donc, comme mentionné par les lignes ci-dessus comment le résoudre (importation de niveau supérieur), je procède aux modifications suivantes:

# change
product = srlzprod.ProductsSerializers(fields=['id','name',],read_only=True,)
# by 
product = serializers.SerializerMethodField()

# and create the following method and call from there the required serializer class
def get_product(self, obj):
        from products import serializers as srlzprod
        p_fields = ['id', 'name', ]
        return srlzprod.ProductsSerializers(
            obj.product, fields=p_fields, many=False,
        ).data

Par conséquent, django runserver a été exécuté sans problème:

./project/settings/manage.py runserver 0:8002 --settings=settings_development_mlazo
Performing system checks...

System check identified no issues (0 silenced).
April 25, 2020 - 13:31:56
Django version 2.0.7, using settings 'settings_development_mlazo'
Starting development server at http://0:8002/
Quit the server with CONTROL-C.

L'état final des lignes de code était le suivant:

from rest_framework import serializers

from common import serializers as srlz
from prices import models as mdlpri

class CampaignsProductsSerializers(srlz.DynamicFieldsModelSerializer):
    bank_name = serializers.CharField(trim_whitespace=True,)
    coupon_type = serializers.SerializerMethodField()
    promotion_description = serializers.SerializerMethodField()
    product = serializers.SerializerMethodField()

    class Meta:
        model = mdlpri.CampaignsProducts
        fields = '__all__'

    def get_product(self, obj):
        from products import serializers as srlzprod
        p_fields = ['id', 'name', ]
        return srlzprod.ProductsSerializers(
            obj.product, fields=p_fields, many=False,
        ).data

J'espère que cela pourrait être utile pour tout le monde.

Salutations,

Manuel Lazo
la source
0

Dans mon cas, travaillant avec python 2.7 avec la version numpy 1.15.0, cela fonctionnait avec

pip install statsmodels=="0.10.0"
Mondaa
la source
0

SoLvEd

Python recherche l'objet a dans votre module a.py.

Soit RENAME ce fichier à autre chose ou de l' utilisation

from __future__ import absolute_import 

en haut de votre module a.py.

hassanzadeh.sd
la source