AttributeError: l'oggetto 'module' non ha attributi


194

Ho due moduli 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"

Quando corro a.py, ottengo:

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

Cosa significa l'errore? Come lo aggiusto?


Nota che le tue domande sono molto simili a questa risposta. Apparentemente il codice in questa risposta funziona solo trovare, ma il tuo no? stackoverflow.com/a/7336880/565879
Buttons840

Risposte:


189

Hai reciproche importazioni di alto livello, che è quasi sempre una cattiva idea.

Se devi davvero importare reciprocamente in Python, il modo per farlo è importarli all'interno di una funzione:

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

Ora a.py può tranquillamente fare import bsenza causare problemi.

(A prima vista potrebbe sembrare che cause_a_to_do_something()sarebbe estremamente inefficiente perché lo fa importogni volta che lo chiami, ma in effetti il ​​lavoro di importazione viene eseguito solo la prima volta. La seconda e le successive volte che importi un modulo, è un'operazione rapida. )


93

Ho anche visto questo errore quando inavvertitamente nomina un modulo con lo stesso nome di uno dei moduli Python standard. Ad esempio, avevo un modulo chiamato commandsche è anche un modulo di libreria Python. Ciò si è rivelato difficile da rintracciare poiché ha funzionato correttamente nel mio ambiente di sviluppo locale ma non è riuscito con l'errore specificato durante l'esecuzione su Google App Engine.


42

Il problema è la dipendenza circolare tra i moduli. aimportazioni be bimportazioni a. Ma uno di questi deve essere caricato per primo - in questo caso python finisce per inizializzare il modulo aprima be b.hi()non esiste ancora quando si tenta di accedervi a.


21

Ho riscontrato questo errore facendo riferimento a un enum che è stato importato in modo errato, ad esempio:

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

Importazione corretta:

from package.MyEnumClass import MyEnumClass

Spero che aiuti qualcuno


7

Ho riscontrato questo errore perché il modulo non è stato effettivamente importato. Il codice era simile al seguente:

import a.b, a.c

# ...

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

L'ultima riga ha provocato un AttributeError. La causa era che non avevo notato che i sottomoduli di a( a.be a.c) erano stati importati esplicitamente e supponevo che la importdichiarazione fosse effettivamente importata a.


6

Ho affrontato lo stesso problema. riparato usando reload.

import the_module_name
from importlib import reload
reload(the_module_name)

5

Ho riscontrato questo problema quando ho verificato da Git una versione precedente di un repository. Git ha sostituito i miei .pyfile, ma ha lasciato i .pycfile non tracciati . Poiché i .pyfile e i .pycfile non erano sincronizzati, il importcomando in un .pyfile non è riuscito a trovare il modulo corrispondente nei .pycfile.

La soluzione era semplicemente eliminare i .pycfile e lasciarli rigenerare automaticamente.


È possibile utilizzare questo comando per eliminare tutti i .pycfile:find . -name "*.pyc" -exec rm -f {} \;
Ollie

4

su Ubuntu 18.04 ( virtualenv , python.3.6.x ), il seguente frammento di ricarica ha risolto il problema per me:

main.py

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

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

dove:

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

per ulteriori controlli sulla documentazione : qui


3

Tutte le risposte sopra sono fantastiche, ma mi piacerebbe venire qui. Se non hai riscontrato alcun problema sopra menzionato, prova a chiarire l'ambiente di lavoro. Ha funzionato per me.


0

Non sono sicuro di come, ma la modifica seguente ha risolto il mio problema:

Avevo il nome del file e lo stesso nome di importazione per es. avevo il nome del file come emoji.py e stavo cercando di importare emoji. Ma la modifica del nome del file ha risolto il problema.

Spero che sia d'aiuto


0

Le importazioni circolari causano problemi, ma Python ha dei modi per mitigarlo.

Il problema è quando si esegue python a.py, viene eseguito a.pyma non contrassegnato come importato come modulo. Quindi a sua volta a.py-> modulo di importazione b -> modulo di importazione a -> modulo di importazione b. L'ultima importazione a no-op dal momento che b è attualmente in fase di importazione e Python protegge da ciò. E b è un modulo vuoto per ora. Quindi, quando viene eseguito b.hi(), non riesce a trovare nulla.

Si noti che quello b.hi()che è stato eseguito è durante a.py-> modulo b -> modulo a, non a.pydirettamente.

Nel tuo esempio specifico, puoi semplicemente eseguire python -c 'import a'al livello superiore, quindi la prima esecuzione di a.pyviene registrata come importazione di un modulo.


0

L' ordine dell'importazione era il motivo per cui avevo problemi:

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

Solo un altro esempio di come potrebbe apparire, simile alla risposta di RichieHindie, ma con le classi.


0

Ho affrontato questo problema molte volte, ma non ho cercato di approfondire. Ora capisco il problema principale.

Questa volta il mio problema era importare i serializzatori (django e restframework) da diversi moduli come il seguente:

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

Stavo riscontrando un problema come questo:

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

Quello che volevo realizzare era il seguente:

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,)

Quindi, come indicato nelle righe sopra come risolverlo (importazione di livello superiore), procedo alle seguenti modifiche:

# 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

Pertanto, django ran server è stato eseguito senza problemi:

./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.

Lo stato finale delle righe di codice era il seguente:

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

Spero che questo possa essere utile per tutti gli altri.

Saluti,


0

Nel mio caso lavorando con Python 2.7 con numpy versione 1.15.0, ha funzionato con

pip install statsmodels=="0.10.0"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.