AttributeError: วัตถุ 'โมดูล' ไม่มีแอตทริบิวต์


193

ฉันมีโมดูลหลามสองโมดูล:

a.py

import b

def hello():
  print "hello"

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

b.py

import a

def hi():
  print "hi"

เมื่อฉันวิ่งa.pyฉันจะได้รับ:

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

ข้อผิดพลาดหมายถึงอะไร ฉันจะแก้ไขได้อย่างไร


โปรดทราบว่าคำถามของคุณคล้ายกับคำตอบนี้มาก เห็นได้ชัดว่ารหัสในคำตอบนี้ใช้งานได้ แต่คุณไม่พบใช่ไหม stackoverflow.com/a/7336880/565879
Buttons840

คำตอบ:


188

คุณมีการนำเข้าระดับบนสุดซึ่งกันและกันเป็นความคิดที่ไม่ดี

หากคุณต้องมีการนำเข้าร่วมกันใน Python วิธีที่จะทำคือการนำเข้าสิ่งเหล่านั้นภายในฟังก์ชั่น:

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

ตอนนี้ a.py สามารถทำได้อย่างปลอดภัยimport bโดยไม่ทำให้เกิดปัญหา

(อย่างรวดเร็วก่อนอาจปรากฏว่าcause_a_to_do_something()จะไม่มีประสิทธิภาพอย่างมหาศาลเพราะมันimportทุกครั้งที่คุณเรียกมัน แต่ในความเป็นจริงงานนำเข้าเท่านั้นที่จะได้รับการดำเนินการในครั้งแรกครั้งที่สองและต่อมาคุณนำเข้าโมดูลมันเป็นการดำเนินการอย่างรวดเร็ว )


93

ฉันได้เห็นข้อผิดพลาดนี้เช่นกันเมื่อตั้งชื่อโมดูลที่มีชื่อเดียวกันกับโมดูล Python มาตรฐานโดยไม่ตั้งใจ เช่นฉันมีโมดูลที่เรียกว่าcommandsซึ่งเป็นโมดูลห้องสมุดหลาม สิ่งนี้พิสูจน์ได้ว่าเป็นเรื่องยากที่จะติดตามเพราะมันทำงานอย่างถูกต้องในสภาพแวดล้อมการพัฒนาในท้องถิ่นของฉัน แต่ล้มเหลวด้วยข้อผิดพลาดที่ระบุเมื่อทำงานบน Google App Engine


42

ปัญหาคือการพึ่งพาแบบวงกลมระหว่างโมดูล aการนำเข้าbและนำเข้าb aแต่หนึ่งในนั้นต้องโหลดแรก - กรณีนี้หลามปลายขึ้นเริ่มต้นโมดูลaก่อนbและb.hi()ไม่ได้อยู่ aแต่เมื่อคุณพยายามที่จะเข้าถึงได้ใน


21

ฉันได้รับข้อผิดพลาดนี้โดยอ้างอิง enum ซึ่งนำเข้ามาในทางที่ผิดเช่น:

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

นำเข้าที่ถูกต้อง:

from package.MyEnumClass import MyEnumClass

หวังว่าจะช่วยใครซักคน


7

ฉันพบข้อผิดพลาดนี้เพราะโมดูลไม่ได้นำเข้าจริง รหัสดูเหมือนว่านี้:

import a.b, a.c

# ...

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

AttributeErrorบรรทัดสุดท้ายผลในการ สาเหตุคือการที่ฉันล้มเหลวที่จะแจ้งให้ทราบว่า submodules ของa( a.bและa.c) ได้รับอย่างชัดเจนนำเข้าและสันนิษฐานว่าเป็นคำสั่งที่นำเข้าจริงimporta


6

ฉันประสบปัญหาเดียวกัน reloadแก้ไขโดยใช้

import the_module_name
from importlib import reload
reload(the_module_name)

5

ฉันพบปัญหานี้เมื่อฉันตรวจสอบที่เก็บรุ่นเก่ากว่าจากคอมไพล์ Git มาแทนที่.pyไฟล์ของฉันแต่ปล่อย.pycไฟล์ที่ไม่ได้ติดตาม เนื่องจาก.pyไฟล์และ.pycไฟล์ต่างซิงค์กันimportคำสั่งใน.pyไฟล์จึงไม่สามารถหาโมดูลที่เกี่ยวข้องใน.pycไฟล์ได้

การแก้ปัญหาคือเพียงการลบ.pycไฟล์และปล่อยให้พวกเขาสร้างใหม่โดยอัตโนมัติ


คุณสามารถใช้คำสั่งนี้เพื่อลบ.pycไฟล์ทั้งหมด:find . -name "*.pyc" -exec rm -f {} \;
Ollie

4

บนUbuntu 18.04 ( virtualenv , python.3.6.x ) ตัวอย่างการโหลดต่อไปนี้แก้ปัญหาสำหรับฉัน:

main.py

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

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

ที่อยู่:

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

สำหรับการตรวจสอบเอกสารเพิ่มเติม: ที่นี่


3

คำตอบทั้งหมดข้างต้นนั้นยอดเยี่ยม แต่ฉันต้องการที่จะพูดสอดที่นี่ หากคุณไม่พบปัญหาใด ๆ ที่กล่าวถึงข้างต้นลองล้างสภาพแวดล้อมการทำงานของคุณ มันใช้งานได้สำหรับฉัน


0

ไม่แน่ใจว่าอย่างไร แต่การเปลี่ยนแปลงด้านล่างเรียงลำดับปัญหาของฉัน:

ฉันมีชื่อไฟล์และชื่อนำเข้าเหมือนกันเช่นฉันมีชื่อไฟล์เป็น emoji.py และฉันพยายามนำเข้าอิโมจิ แต่การเปลี่ยนชื่อไฟล์แก้ไขปัญหาได้

หวังว่ามันจะช่วย


0

การนำเข้าแบบวงกลมทำให้เกิดปัญหา แต่ Python มีวิธีในการบรรเทาปัญหาที่มีในตัว

ปัญหาคือเมื่อคุณเรียกใช้python a.pyมันทำงานa.pyแต่ไม่ทำเครื่องหมายนำเข้าเป็นโมดูล ดังนั้นในทางกลับกันa.py-> โมดูลนำเข้า b -> นำเข้าโมดูล a -> นำเข้าโมดูล b การนำเข้าครั้งล่าสุดไม่มีการดำเนินการเนื่องจาก b กำลังถูกนำเข้าและ Python ได้รับการป้องกัน และ b เป็นโมดูลว่างเปล่าในตอนนี้ ดังนั้นเมื่อมันรันb.hi()มันไม่สามารถหาอะไรได้เลย

โปรดทราบว่าการb.hi()ดำเนินการนั้นอยู่ในช่วงa.py-> โมดูล b -> โมดูล a ไม่ใช่a.pyโดยตรง

ในตัวอย่างเฉพาะของคุณคุณสามารถเรียกใช้python -c 'import a'ที่ระดับบนสุดดังนั้นการดำเนินการครั้งแรกของการa.pyลงทะเบียนเป็นการนำเข้าโมดูล


0

การสั่งซื้อของการนำเข้าเป็นเหตุผลที่ว่าทำไมผมมีปัญหา:

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

เป็นอีกตัวอย่างของลักษณะที่อาจคล้ายกับคำตอบของ RichieHindie แต่มีคลาส


0

ฉันได้ข้ามกับปัญหานี้หลายครั้ง แต่ฉันไม่ได้พยายามที่จะขุดลึกลงไปเกี่ยวกับเรื่องนี้ ตอนนี้ฉันเข้าใจประเด็นหลักแล้ว

เวลานี้ปัญหาของฉันคือการนำเข้า Serializers (django และ restframework) จากโมดูลต่าง ๆ เช่นต่อไปนี้:

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

ฉันพบปัญหาเช่นนี้:

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

สิ่งที่ฉันต้องการสำเร็จคือต่อไปนี้:

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

ดังนั้นตามที่กล่าวไว้ข้างต้นวิธีการแก้ปัญหา (นำเข้าระดับบนสุด) ฉันดำเนินการเปลี่ยนแปลงต่อไปนี้:

# 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

ดังนั้น django runserver จึงถูกเรียกใช้โดยไม่มีปัญหา:

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

สถานะสุดท้ายของบรรทัดรหัสคือ:

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

หวังว่านี่จะเป็นประโยชน์สำหรับคนอื่น ๆ

ทักทาย,


0

ในกรณีของฉันทำงานกับ python 2.7 กับ numpy รุ่น 1.15.0 มันทำงานด้วย

pip install statsmodels=="0.10.0"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.