AttributeError: obiekt „module” nie ma atrybutu


193

Mam dwa moduły 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"

Kiedy biegnę a.py, dostaję:

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

Co oznacza błąd? Jak to naprawić?


Pamiętaj, że twoje pytania są bardzo podobne do tej odpowiedzi. Najwyraźniej kod w tej odpowiedzi działa tylko znaleźć, ale twój nie? stackoverflow.com/a/7336880/565879
Buttons840

Odpowiedzi:


188

Masz wzajemny import najwyższego poziomu, co prawie zawsze jest złym pomysłem.

Jeśli naprawdę potrzebujesz wzajemnych importów w Pythonie, sposobem na to jest zaimportowanie ich w ramach funkcji:

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

Teraz a.py może bezpiecznie obejść się import bbez powodowania problemów.

(Na pierwszy rzut oka może się wydawać, że cause_a_to_do_something()byłoby to bardzo nieefektywne, ponieważ robi się to za importkażdym razem, gdy go wywołujesz, ale w rzeczywistości importowanie odbywa się tylko za pierwszym razem. Za drugim i następnym razem, gdy importujesz moduł, jest to szybka operacja. )


92

Widziałem także ten błąd, gdy nieumyślnie nadano nazwę modułowi o tej samej nazwie, co jeden ze standardowych modułów Pythona. Np. Miałem moduł o nazwie, commandsktóry jest również modułem biblioteki Pythona. To okazało się trudne do wyśledzenia, ponieważ działało poprawnie w moim lokalnym środowisku programistycznym, ale nie powiodło się z określonym błędem podczas uruchamiania w Google App Engine.


42

Problem polega na okrągłej zależności między modułami. aimport bi bimport a. Ale jeden z nich musi zostać załadowany jako pierwszy - w tym przypadku python kończy inicjalizację modułu awcześniej bi b.hi()nie istnieje jeszcze, gdy próbujesz uzyskać do niego dostęp a.


21

Wystąpił ten błąd, odwołując się do wyliczenia, które zostało zaimportowane w niewłaściwy sposób, np .:

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

Prawidłowy import:

from package.MyEnumClass import MyEnumClass

Mam nadzieję, że komuś pomoże


7

Wystąpił ten błąd, ponieważ moduł nie został faktycznie zaimportowany. Kod wyglądał następująco:

import a.b, a.c

# ...

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

Ostatnia linia zakończyła się AttributeError. Przyczyną było to, że nie zauważyłem, że podmoduły a( a.bi a.c) zostały wyraźnie zaimportowane, i założyłem, że importinstrukcja faktycznie zaimportowana a.


6

Napotkałem ten sam problem. naprawione za pomocą reload.

import the_module_name
from importlib import reload
reload(the_module_name)

5

Natrafiłem na ten problem, gdy sprawdziłem starszą wersję repozytorium od git. Git zastąpił moje .pypliki, ale zostawił nieśledzone .pycpliki. Ponieważ .pypliki i .pycpliki nie były zsynchronizowane, importpolecenie w .pypliku nie mogło znaleźć odpowiedniego modułu w .pycplikach.

Rozwiązaniem było po prostu usunięcie .pycplików i automatyczne ich ponowne wygenerowanie.


Możesz użyć tego polecenia, aby usunąć wszystkie .pycpliki:find . -name "*.pyc" -exec rm -f {} \;
Ollie

4

w Ubuntu 18.04 ( virtualenv , python.3.6.x ) następujący fragment przeładowania rozwiązał problem:

main.py

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

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

gdzie:

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

więcej dokumentacji sprawdź: tutaj


3

Wszystkie powyższe odpowiedzi są świetne, ale chciałbym tu zagrać. Jeśli nie zauważyłeś żadnego z wyżej wymienionych problemów, spróbuj wyczyścić swoje środowisko pracy. To zadziałało dla mnie.


0

Nie jestem pewien, w jaki sposób, ale poniższe zmiany posortowały mój problem:

Miałem taką samą nazwę pliku i nazwę importu, np. miałem nazwę pliku jako emoji.py i próbowałem zaimportować emoji. Ale zmiana nazwy pliku rozwiązała problem.

Mam nadzieję, że to pomaga


0

Importowanie cykliczne powoduje problemy, ale Python ma sposoby na złagodzenie tego problemu.

Problem polega na tym python a.py, że po uruchomieniu działa, a.pyale nie oznacza, że ​​został zaimportowany jako moduł. Z kolei a.py-> moduł importu b -> moduł importu a -> moduł importu b. Ostatni import, w którym nie ma operacji, ponieważ b jest obecnie importowany i Python chroni przed tym. A b jest na razie pustym modułem. Kiedy więc się uruchomi b.hi(), nic nie znajdzie.

Zauważ, b.hi()że wykonano to podczas a.py-> modułu b -> modułu a, a nie a.pybezpośrednio.

W twoim przykładzie możesz po prostu uruchomić python -c 'import a'na najwyższym poziomie, więc pierwsze wykonanie a.pyjest rejestrowane jako import modułu.


0

Zamówienie importującej było powodem miałem problemy:

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

Kolejny przykład tego, jak może to wyglądać, podobnie do odpowiedzi RichieHindie, ale z klasami.


0

Wiele razy podchodziłem do tego problemu, ale nie próbowałem go głębiej badać. Teraz rozumiem główny problem.

Tym razem moim problemem był import Serializatorów (django i restframework) z różnych modułów, takich jak:

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

Miałem taki problem:

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

To, co chciałem osiągnąć, było następujące:

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

Tak więc, jak wspomniano w wierszach powyżej, jak to rozwiązać (import najwyższego poziomu), przystępuję do następujących zmian:

# 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

Dlatego django runserver został uruchomiony bez problemów:

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

Ostateczny stan linii kodu był następujący:

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

Mam nadzieję, że to może być pomocne dla wszystkich innych.

Pozdrowienia,


0

W moim przypadku działał z Pythonem 2.7 z wersją numpy 1.15.0

pip install statsmodels=="0.10.0"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.