AttributeError: 'module' nesnesinin niteliği yok


193

İki python modülüm var:

a.py

import b

def hello():
  print "hello"

print "a.py"
print hello()
print b.hi()

b.py

import a

def hi():
  print "hi"

Koştuğumda a.py, anladım:

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

Hata ne anlama geliyor? Nasıl düzeltebilirim?


Sorularınızın bu cevaba çok benzediğini unutmayın. Görünüşe göre bu cevap kodu bulmak sadece çalışır, ama senin değil mi? stackoverflow.com/a/7336880/565879
Düğmeler840

Yanıtlar:


188

Karşılıklı üst düzey ithalatınız var, bu neredeyse her zaman kötü bir fikir.

Python'da gerçekten karşılıklı ithalat yapmanız gerekiyorsa, bunu yapmanın yolu bunları bir işlev içinde içe aktarmaktır:

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

Şimdi a.py import bproblemlere neden olmadan güvenle yapabilir .

(İlk bakışta cause_a_to_do_something(), importher seferinde aradığınızda çok verimsiz görünebilir , ancak aslında alma işi sadece ilk kez yapılır. Bir modülü ikinci ve sonraki kez içe aktardığınızda, hızlı bir işlemdir. )


93

Ayrıca, standart Python modüllerinden biriyle aynı ada sahip bir modülü adlandırırken bu hatayı gördüm. Örneğin commandsPython kütüphanesi modülü olan bir modülüm vardı . Yerel geliştirme ortamımda doğru bir şekilde çalıştığı, ancak Google App Engine'de çalışırken belirtilen hatayla başarısız olduğu için bunun izlenmesi zor oldu.


42

Sorun, modüller arasındaki dairesel bağımlılıktır. aithalat bve bithalat a. Ama bunlardan birinin önce yüklenmesi gerekiyor - bu durumda python modülü daha aönce başlatmaya başlar bve b.hi()ona erişmeye çalıştığınızda henüz mevcut değildir a.


21

Yanlış bir şekilde içe aktarılan bir numaralandırma başvurarak bu hatayı aldım, örneğin:

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

Doğru içe aktarma:

from package.MyEnumClass import MyEnumClass

Birisine yardımcı olan umarım


7

Bu hatayla karşılaştım çünkü modül aslında içe aktarılmadı. Kod şöyle görünüyordu:

import a.b, a.c

# ...

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

Son satır bir AttributeError. Bunun nedeni, a( a.bve a.c) alt modüllerinin açıkça içe aktarıldığını fark etmememdi ve importifadenin gerçekten içe aktarıldığını varsaydı a.


6

Aynı sorunla karşılaştım. kullanarak sabitlenir reload.

import the_module_name
from importlib import reload
reload(the_module_name)

5

Git'ten bir deponun eski bir sürümünü kullanıma aldığımda bu sorunla karşılaştım. Git .pydosyalarımı değiştirdi , ancak izlenmemiş .pycdosyaları bıraktı . Yana .pydosya ve .pycdosyaları senkronize değil, importbir komut .pydosyasındaki ilgili modül bulamadık .pycdosyaları.

Çözüm, .pycdosyaları silmek ve otomatik olarak yeniden oluşturulmasına izin vermekti.


Tüm .pycdosyaları silmek için bu komutu kullanabilirsiniz :find . -name "*.pyc" -exec rm -f {} \;
Ollie

4

üzerinde ubuntu 18.04 ( Virtualenv , python.3.6.x ), aşağıdaki yeniden pasajı çözüldü benim için problem:

main.py

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

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

nerede:

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

daha fazla dokümantasyon kontrolü için: burada


3

Yukarıdaki tüm cevaplar harika, ama buraya gelmek istiyorum. Yukarıda belirtilen herhangi bir sorunu tespit etmediyseniz, çalışma ortamınızı temizlemeyi deneyin. Benim için çalıştı.


0

Nasıl emin değilim ama aşağıdaki değişiklik sorunumu sıraladı:

i dosya adı ve ithalat adı aynı emoji.py olarak dosya adı vardı ve ben emoji almaya çalışıyordu. Ancak dosyanın adını değiştirmek sorunu çözdü.

Umarım yardımcı olur


0

Dairesel ithalat sorunlara neden olur, ancak Python'un yerleşik azaltma yolları vardır.

Sorun, çalıştırdığınızda python a.py, çalıştırılıyor a.pyancak bir modül olarak içe aktarılmış olarak işaretlenmiyor. Böylece a.py-> ithalat modülü b -> ithalat modülü a -> ithalat modülü b. Son içe aktarma işlemi, b şu anda içe aktarıldığından beri op-no'ludur ve Python buna karşı koruma sağlar. Ve b şimdilik boş bir modül. Böylece,b.hi() hiçbir şey bulamaz.

Yürütülenlerin doğrudan değil, -> modül b -> modül a b.hi()sırasında olduğunu unutmayın .a.pya.py

Özel örneğinizde, sadece python -c 'import a'üst düzeyde çalışabilirsiniz , böylece ilk yürütme a.pybir modül almak olarak kaydedilir.


0

sipariş ithal I sorunlarınız sebebi de buydu:

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

Nasıl göründüğüne dair başka bir örnek, RichieHindie'nin cevabına benzer, ancak sınıflarla.


0

Bu konuyu birçok kez geçtim, ama daha derine inmeye çalışmadım. Şimdi ana konuyu anlıyorum.

Bu kez sorunum, aşağıdaki gibi farklı modüllerden Serializer'ları (django ve restframework) almaktı:

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

Ben böyle bir sorun alıyordu:

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

Yapmak istediğim şey şuydu:

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

Bu nedenle, yukarıdaki satırların belirttiği gibi (üst düzey içe aktarma), aşağıdaki değişiklikleri yapmaya devam ediyorum:

# 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

Bu nedenle, django runserver sorunsuz yürütüldü:

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

Kod satırlarının son durumu şuydu:

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

Umarım bu herkes için faydalı olabilir.

Selamlar,


0

Benim durumumda numpy sürüm 1.15.0 ile python 2.7 ile çalışmak, ile çalıştı

pip install statsmodels=="0.10.0"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.