AttributeError:'module'对象没有属性

时间:2009-08-08 23:12:21

标签: python attributeerror

我有两个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"

当我运行a.py时,我得到:

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

错误是什么意思?我该如何解决?

17 个答案:

答案 0 :(得分:162)

你有共同的顶级导入,这几乎总是一个坏主意。

如果你真的必须在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,但事实上导入工作只是第一次完成。以及随后导入模块的时间,这是一个快速操作。)

答案 1 :(得分:80)

当无意中命名一个与标准Python模块同名的模块时,我也看到了这个错误。例如。我有一个名为commands的模块,它也是一个Python库模块。这被证明很难追踪,因为它在我的本地开发环境中正常工作,但在Google App Engine上运行时因指定的错误而失败。

答案 2 :(得分:40)

问题是模块之间的循环依赖性。 a导入bb导入a。但是其中一个需要先加载 - 在这种情况下,python最终会在a之前初始化模块b,而当你尝试在{{1}中访问它时b.hi()不存在}}

答案 3 :(得分:17)

我通过引用以错误方式导入的枚举来获得此错误,例如:

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

正确导入:

from package.MyEnumClass import MyEnumClass

希望能帮到某人

答案 4 :(得分:7)

我遇到此错误,因为模块实际上并未导入。代码看起来像这样:

import a.b, a.c

# ...

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

最后一行产生AttributeError。原因是我没有注意到aa.ba.c)的子模块是显式导入的,并假设{{1} }语句实际导入import

答案 5 :(得分:3)

当我从git中检出较旧版本的存储库时遇到了这个问题。 Git替换了我的.py文件,但留下了未跟踪的.pyc文件。由于.py文件和.pyc文件不同步,因此import文件中的.py命令在.pyc文件中找不到相应的模块。

解决方案只是删除.pyc文件,并让它们自动重新生成。

答案 6 :(得分:2)

以上所有答案都很棒,但我想在这里发言。如果您没有发现上述任何问题,请尝试清理您的工作环境。它对我有用。

答案 7 :(得分:2)

ubuntu 18.04 virtualenv python.3.6.x )上,以下 reload 片段为我解决了问题:

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

有关更多文档的检查,请检查:here

答案 8 :(得分:0)

对我来说,此错误的原因是,有一个与我要导入的python模块同名的文件夹。

|-- core  <-- empty directory on the same level as the module that throws the error
|-- core.py

然后python将文件夹视为python包,并尝试从该空包“ core”而不是从core.py导入。

好像由于某种原因git在分支切换期间离开了那个空文件夹

所以我刚刚删除了该文件夹,一切都像一个符咒一样

答案 9 :(得分:0)

已解决

Python正在 a.py 模块中寻找对象。

重命名该文件至其他文件或使用

from __future__ import absolute_import 

位于 a.py 模块顶部。

答案 10 :(得分:0)

在我使用numpy 1.15.0的python 2.7的情况下,它可以使用

pip install statsmodels=="0.10.0"

答案 11 :(得分:0)

我已经多次遇到这个问题,但是我没有尝试更深入地研究它。现在我了解了主要问题。

这一次,我的问题是从诸如以下的不同模块中导入序列化器(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

希望这对其他人有帮助。

问候,

答案 12 :(得分: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的回答,但带有类。

答案 13 :(得分:0)

@ MD5对我一样,请尝试更改模块名称或直接导入功能

答案 14 :(得分:0)

我遇到了同样的问题。 通过使用reload进行修复。

import the_module_name
from importlib import reload
reload(the_module_name)

答案 15 :(得分:0)

圆形导入会引起问题,但是Python有一些方法可以缓解这种情况。

问题是当您运行python a.py时,它运行a.py但未将其标记为模块导入。因此依次a.py->导入模块b->导入模块a->导入模块b。自从b导入以来,最后一次导入no-op,Python对此进行了防范。 b现在是一个空模块。因此,当它执行b.hi()时,找不到任何东西。

请注意,执行的b.hi()是在a.py->模块b->模块a中,而不是直接在a.py中。

在您的特定示例中,您只可以在顶层运行python -c 'import a',因此a.py的首次执行被注册为导入模块。

答案 16 :(得分:0)

不知道如何,但以下更改对我的问题进行了排序:

我的文件名和导入名称相同,例如,我的文件名为emoji.py,并且我试图导入表情符号。但是更改文件名解决了这个问题。

希望如此有帮助