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ć?

Stephen Hsu
źródło
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. )

RichieHindle
źródło
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.

Lucrussell
źródło
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.

coś
źródło
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

Stoyan
źródło
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.

Dag Høidahl
źródło
6

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

import the_module_name
from importlib import reload
reload(the_module_name)
Tylko my
źródło
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.

krak
źródło
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

Behzad Sezari
źródło
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.

Jian
źródło
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

MD5
źródło
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.

Hot.PxL
źródło
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.

jmunsch
źródło
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,

Manuel Lazo
źródło
0

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

pip install statsmodels=="0.10.0"
Mondaa
źródło