AttributeError: objek 'module' tidak memiliki atribut

193

Saya memiliki dua modul 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"

Ketika saya berlari a.py, saya mendapatkan:

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

Apa artinya kesalahan itu? Bagaimana saya memperbaikinya?

Stephen Hsu
sumber
Perhatikan bahwa pertanyaan Anda sangat mirip dengan jawaban ini. Ternyata kode dalam jawaban ini berfungsi hanya temukan, tetapi Anda tidak? stackoverflow.com/a/7336880/565879
Buttons840

Jawaban:

188

Anda memiliki impor tingkat atas bersama, yang hampir selalu merupakan ide yang buruk.

Jika Anda benar-benar harus saling mengimpor dengan Python, cara untuk melakukannya adalah dengan mengimpornya dalam suatu fungsi:

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

Sekarang a.py dapat melakukannya dengan aman import btanpa menimbulkan masalah.

(Sepintas mungkin tampak cause_a_to_do_something()sangat tidak efisien karena melakukan importsetiap kali Anda menyebutnya, tetapi pada kenyataannya pekerjaan impor hanya dilakukan pertama kali. Kali kedua dan selanjutnya Anda mengimpor modul, ini adalah operasi yang cepat. )

RichieHindle
sumber
92

Saya juga melihat kesalahan ini ketika secara tidak sengaja memberi nama modul dengan nama yang sama dengan salah satu modul Python standar. Misalnya saya punya modul yang disebut commandsyang juga merupakan modul perpustakaan Python. Ini terbukti sulit dilacak karena berfungsi dengan benar di lingkungan pengembangan lokal saya tetapi gagal dengan kesalahan yang ditentukan saat berjalan di Google App Engine.

lucrussell
sumber
42

Masalahnya adalah ketergantungan melingkar antara modul. aimpor bdan bimpor a. Tetapi salah satu dari mereka perlu dimuat terlebih dahulu - dalam hal ini python akhirnya menginisialisasi modul asebelumnya bdan b.hi()belum ada ketika Anda mencoba mengaksesnya a.

sth
sumber
21

Saya mendapatkan kesalahan ini dengan mereferensikan enum yang diimpor dengan cara yang salah, misalnya:

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

Impor yang benar:

from package.MyEnumClass import MyEnumClass

Semoga itu bisa membantu seseorang

Stoyan
sumber
7

Saya mengalami kesalahan ini karena modul tidak benar-benar diimpor. Kode tersebut terlihat seperti ini:

import a.b, a.c

# ...

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

Baris terakhir menghasilkan AttributeError. Penyebabnya adalah saya gagal memperhatikan bahwa submodul a( a.bdan a.c) diimpor secara eksplisit , dan mengasumsikan bahwa importpernyataan tersebut benar-benar diimpor a.

Dag Høidahl
sumber
6

Saya menghadapi masalah yang sama. diperbaiki dengan menggunakan reload.

import the_module_name
from importlib import reload
reload(the_module_name)
Hanya kita
sumber
5

Saya mengalami masalah ini ketika saya memeriksa versi lama dari repositori dari git. Git mengganti .pyfile saya , tetapi meninggalkan .pycfile yang tidak terlacak . Karena .pyfile dan .pycfile tidak sinkron, importperintah dalam .pyfile tidak dapat menemukan modul yang sesuai dalam .pycfile.

Solusinya adalah dengan menghapus .pycfile, dan membiarkannya dibuat ulang secara otomatis.

craq
sumber
Anda dapat menggunakan perintah ini untuk menghapus semua .pycfile:find . -name "*.pyc" -exec rm -f {} \;
Ollie
4

di ubuntu 18.04 ( virtualenv , python.3.6.x ), cuplikan reload berikut memecahkan masalah untuk saya:

main.py

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

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

dimana:

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

untuk dokumentasi lebih lanjut, periksa di sini

Behzad Sezari
sumber
3

Semua jawaban di atas bagus, tetapi saya ingin berpadu di sini. Jika Anda tidak menemukan masalah yang disebutkan di atas, coba bersihkan lingkungan kerja Anda. Ini berhasil untuk saya.

Jian
sumber
0

Tidak yakin bagaimana tetapi perubahan di bawah ini mengurutkan masalah saya:

saya mempunyai nama file dan impor nama yang sama untuk misalnya saya punya nama file sebagai emoji.py dan saya mencoba mengimpor emoji. Tetapi mengubah nama file memecahkan masalah.

Semoga ini bisa membantu

MD5
sumber
0

Impor sirkular menyebabkan masalah, tetapi Python memiliki cara untuk memitigasi bawaannya.

Masalahnya adalah ketika Anda menjalankan python a.py, itu berjalan a.pytetapi tidak menandainya diimpor sebagai modul. Jadi pada gilirannya a.py-> modul impor b -> modul impor a -> modul impor b. Impor terakhir no-op karena b saat ini sedang diimpor dan Python menjaga itu. Dan b adalah modul kosong untuk saat ini. Jadi saat dijalankanb.hi() , ia tidak dapat menemukan apa pun.

Perhatikan bahwa b.hi()yang dieksekusi adalah selama a.py-> modul b -> modul a, tidak a.pysecara langsung.

Dalam contoh spesifik Anda, Anda bisa menjalankannya python -c 'import a'di tingkat atas, sehingga eksekusi pertama a.pyterdaftar sebagai pengimporan modul.

Hot.PxL
sumber
0

The rangka dari impor adalah alasan mengapa saya mengalami masalah:

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

Contoh lain tentang tampilannya, mirip dengan jawaban RichieHindie, tetapi dengan kelas.

jmunsch
sumber
0

Saya telah banyak kali berselisih dengan masalah ini, tetapi saya tidak mencoba menggali lebih dalam tentang hal ini. Sekarang saya mengerti masalah utama.

Kali ini masalah saya mengimpor Serializers (Django dan Restframework) dari modul yang berbeda seperti berikut:

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

Saya mendapatkan masalah seperti ini:

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

Apa yang ingin saya capai adalah sebagai berikut:

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

Jadi, seperti yang disebutkan oleh baris di atas cara menyelesaikannya (impor tingkat atas), saya melanjutkan untuk melakukan perubahan berikut:

# 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

Karena itu, django runserver dijalankan tanpa masalah:

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

Keadaan akhir dari baris kode adalah sebagai berikut:

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

Semoga ini bisa bermanfaat bagi orang lain.

Salam pembuka,

Manuel Lazo
sumber
0

Dalam kasus saya bekerja dengan python 2.7 dengan numpy versi 1.15.0, itu berhasil

pip install statsmodels=="0.10.0"
Mondaa
sumber