Đối tượng AttributionError: 'module' không có thuộc tính


193

Tôi có hai mô-đun 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"

Khi tôi chạy a.py, tôi nhận được:

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

Lỗi này có nghĩa là gì? Làm thế nào để tôi sửa chữa nó?


Lưu ý rằng câu hỏi của bạn rất giống với câu trả lời này. Rõ ràng mã trong câu trả lời này chỉ hoạt động, nhưng của bạn thì không? stackoverflow.com/a/7336880/565879
Nút840

Câu trả lời:


188

Bạn có nhập khẩu cấp cao lẫn nhau, gần như luôn luôn là một ý tưởng tồi.

Nếu bạn thực sự phải nhập lẫn nhau trong Python, cách thực hiện là nhập chúng trong một hàm:

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

Bây giờ a.py có thể làm một cách an toàn import bmà không gây ra vấn đề.

(Thoạt nhìn có vẻ như cause_a_to_do_something()nó cực kỳ kém hiệu quả vì importmỗi lần bạn gọi nó, nhưng thực tế công việc nhập chỉ được thực hiện lần đầu tiên. Lần thứ hai và lần sau bạn nhập mô-đun, đó là thao tác nhanh. )


92

Tôi cũng đã thấy lỗi này khi vô tình đặt tên một mô-đun có cùng tên với một trong các mô-đun Python tiêu chuẩn. Ví dụ, tôi có một mô-đun được gọi commandslà mô-đun thư viện Python. Điều này tỏ ra khó theo dõi vì nó hoạt động chính xác trên môi trường phát triển cục bộ của tôi nhưng không thành công với lỗi được chỉ định khi chạy trên Google App Engine.


42

Vấn đề là sự phụ thuộc vòng tròn giữa các mô-đun. anhập khẩu bbnhập khẩua . Nhưng một trong số chúng cần được tải trước - trong trường hợp này python kết thúc việc khởi tạo mô-đun atrước đó bb.hi()chưa tồn tại khi bạn cố gắng truy cập nó a.


21

Tôi đã gặp lỗi này bằng cách tham chiếu một enum được nhập sai, ví dụ:

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

Nhập chính xác:

from package.MyEnumClass import MyEnumClass

Mong rằng sẽ giúp được ai đó


7

Tôi gặp lỗi này vì mô-đun không thực sự được nhập. Mã trông như thế này:

import a.b, a.c

# ...

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

Dòng cuối cùng dẫn đến một AttributeError. Nguyên nhân là do tôi đã không nhận thấy rằng các mô hình con của a( a.ba.c) được nhập rõ ràng và cho rằng importcâu lệnh thực sự được nhập a.


6

Tôi phải đối mặt với cùng một vấn đề. cố định bằng cách sử dụng reload.

import the_module_name
from importlib import reload
reload(the_module_name)

Cảm ơn, đây là câu trả lời duy nhất có hiệu quả với tôi :)
TheTechRobo36414519

5

Tôi gặp vấn đề này khi kiểm tra phiên bản cũ hơn của kho lưu trữ từ git. Git đã thay thế .pycác tệp của tôi , nhưng để lại các .pyctệp không bị theo dõi . Vì các .pytệp và .pyctệp không đồng bộ, nên importlệnh trong .pytệp không thể tìm thấy mô-đun tương ứng trong .pyctệp.

Giải pháp đơn giản là xóa các .pyctệp và để chúng được tự động phục hồi.


Bạn có thể sử dụng lệnh này để xóa tất cả .pyccác tệp:find . -name "*.pyc" -exec rm -f {} \;
Ollie

4

trên Ubuntu 18.04 ( virtualenv , python.3.6.x ), đoạn mã tải lại sau đây đã giải quyết vấn đề cho tôi:

chính

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

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

Ở đâu:

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

để biết thêm tài liệu kiểm tra: tại đây


3

Tất cả các câu trả lời ở trên là tuyệt vời, nhưng tôi muốn kêu vang ở đây. Nếu bạn không phát hiện ra bất kỳ vấn đề nào được đề cập ở trên, hãy thử làm rõ môi trường làm việc của bạn. Nó làm việc cho tôi.


0

Không chắc chắn làm thế nào nhưng thay đổi dưới đây đã sắp xếp vấn đề của tôi:

tôi đã có tên của tệp và tên nhập giống nhau, ví dụ như tôi có tên tệp là emoji.py và tôi đã cố gắng nhập biểu tượng cảm xúc. Nhưng thay đổi tên của tập tin đã giải quyết vấn đề.

Hy vọng nó sẽ giúp


0

Nhập khẩu tròn gây ra vấn đề, nhưng Python có cách để giảm thiểu nó tích hợp.

Vấn đề là khi bạn chạy python a.py, nó chạy a.pynhưng không đánh dấu nó được nhập dưới dạng mô-đun. Vì vậy, lần lượt a.py-> nhập mô-đun b -> nhập mô-đun a -> mô-đun nhập b. Lần nhập cuối cùng không có op vì b hiện đang được nhập và Python bảo vệ chống lại điều đó. Và b là một mô-đun trống bây giờ. Vì vậy, khi nó thực thib.hi() , nó không thể tìm thấy bất cứ điều gì.

Lưu ý rằng b.hi()đã thực hiện là trong a.py-> mô-đun b -> mô-đun a, không phải tronga.py trực tiếp.

Trong ví dụ cụ thể của bạn, bạn chỉ có thể chạy python -c 'import a'ở cấp cao nhất, vì vậy lần thực hiện đầu tiên a.pyđược đăng ký là nhập mô-đun.


0

Thứ tự nhập khẩu là lý do tại sao tôi gặp vấn đề:

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

Chỉ là một ví dụ khác về cách nó trông như thế nào, tương tự như câu trả lời của RichieHindie, nhưng với các lớp học.


0

Tôi đã vượt qua vấn đề này nhiều lần, nhưng tôi đã không cố gắng tìm hiểu sâu hơn về nó. Bây giờ tôi hiểu vấn đề chính.

Lần này, vấn đề của tôi là nhập Trình tuần tự hóa (django và restframework) từ các mô-đun khác nhau như sau:

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

Tôi đã gặp một vấn đề như thế này:

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

Những gì tôi muốn thực hiện là như sau:

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

Vì vậy, như đã đề cập trong các dòng trên về cách giải quyết nó (nhập khẩu cấp cao nhất), tôi tiến hành thực hiện các thay đổi sau:

# 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

Do đó, máy chủ django được thực thi mà không gặp vấn đề gì:

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

Trạng thái cuối cùng của các dòng mã như sau:

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

Hy vọng điều này có thể hữu ích cho mọi người khác.

Lời chào hỏi,


0

Trong trường hợp của tôi làm việc với python 2.7 với phiên bản numpy 1.15.0, nó đã hoạt động với

pip install statsmodels=="0.10.0"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.