AttributeError: 'module' object has no attribute [duplicate]
Asked Answered
S

20

254

I have two python modules:

a.py

import b

def hello():
  print "hello"

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

b.py

import a

def hi():
  print "hi"

When I run a.py, I get:

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

What does the error mean? How do I fix it?

Shanghai answered 8/8, 2009 at 23:12 Comment(1)
Note that your questions is very similar to this answer. Apparently the code in this answer works just find, but yours does not? https://mcmap.net/q/111504/-how-to-avoid-circular-imports-in-python-duplicateNickname
H
242

You have mutual top-level imports, which is almost always a bad idea.

If you really must have mutual imports in Python, the way to do it is to import them within a function:

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

Now a.py can safely do import b without causing problems.

(At first glance it might appear that cause_a_to_do_something() would be hugely inefficient because it does an import every time you call it, but in fact the import work only gets done the first time. The second and subsequent times you import a module, it's a quick operation.)

Heat answered 8/8, 2009 at 23:27 Comment(2)
this is more a workaround than a solution IMO.Thurstan
@Thurstan so basically like everything written in python?Doughty
S
119

I have also seen this error when inadvertently naming a module with the same name as one of the standard Python modules. E.g. I had a module called commands which is also a Python library module. This proved to be difficult to track down as it worked correctly on my local development environment but failed with the specified error when running on Google App Engine.

Sophisticate answered 26/6, 2010 at 14:18 Comment(0)
L
54

The problem is the circular dependency between the modules. a imports b and b imports a. But one of them needs to be loaded first - in this case python ends up initializing module a before b and b.hi() doesn't exist yet when you try to access it in a.

Legatee answered 8/8, 2009 at 23:19 Comment(0)
A
30

I got this error by referencing an enum which was imported in a wrong way, e.g.:

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

Correct import:

from package.MyEnumClass import MyEnumClass

Hope that helps someone

Astrakhan answered 16/4, 2015 at 23:32 Comment(0)
C
10

I faced the same issue. fixed by using reload.

import the_module_name
from importlib import reload
reload(the_module_name)
Chladek answered 2/7, 2019 at 2:46 Comment(1)
This is really interesting, any idea why some parts on a module might end up missing?Irrigation
B
8

on ubuntu 18.04 ( virtualenv, python.3.6.x), the following reload snippet solved the problem for me:

main.py

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

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

where:

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

for more documentation check : here

Bernardobernarr answered 10/8, 2019 at 12:51 Comment(0)
H
7

I ran into this problem when I checked out an older version of a repository from git. Git replaced my .py files, but left the untracked .pyc files. Since the .py files and .pyc files were out of sync, the import command in a .py file could not find the corresponding module in the .pyc files.

The solution was simply to delete the .pyc files, and let them be automatically regenerated.

Herzl answered 21/9, 2018 at 2:43 Comment(1)
You can use this command to delete all .pyc files: find . -name "*.pyc" -exec rm -f {} \;Pyrogen
I
6

I experienced this error because the module was not actually imported. The code looked like this:

import a.b, a.c

# ...

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

The last line resulted in an AttributeError. The cause was that I had failed to notice that the submodules of a (a.b and a.c) were explicitly imported, and assumed that the import statement actually imported a.

Idzik answered 24/6, 2016 at 20:26 Comment(0)
S
5

All the above answers are great, but I'd like to chime in here. If you did not spot any issue mentioned above, try clear up your working environment. It worked for me.

Sharell answered 6/6, 2018 at 18:21 Comment(2)
To supplement this answer: when Jian said "clear up your working environment", if you are in Jupyter notebook, you simply "shutdown" your working .ipynb (not the env or machine) and open your .ipynb again, it works for me.Rhyne
or restart your IDA kernel as not everyone using JupyterInterceptor
D
4

Circular imports cause problems, but Python has ways to mitigate it built-in.

The problem is when you run python a.py, it runs a.py but not mark it imported as a module. So in turn a.py -> imports module b -> imports module a -> imports module b. The last import a no-op since b is currently being imported and Python guards against that. And b is an empty module for now. So when it executes b.hi(), it can't find anything.

Note that the b.hi() that got executed is during a.py -> module b -> module a, not in a.py directly.

In your specific example, you can just run python -c 'import a' at top-level, so the first execution of a.py is registered as importing a module.

Desiccate answered 9/1, 2019 at 15:12 Comment(2)
This IS the correct answer IMHO. very well explained.Thurstan
I would add that when he runs python a.py it effectively (start to) runs it (what else), but not mark it as imported .. BECAUSE it IS the __main__ module being executed.Thurstan
W
3

For me, the reason for this error was that there was a folder with the same name as the python module I was trying to import.

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

And python treated that folder as a python package and tried to import from that empty package "core", not from core.py.

Seems like for some reason git left that empty folder during the branches switch

So I just removed that folder and everything worked like a charm

Wholism answered 19/11, 2020 at 8:59 Comment(1)
In this case you can write "from core import core"Derina
N
1

are you saved 'b.py' ? you must save 'b.py' first.

Nolasco answered 11/3, 2022 at 0:50 Comment(4)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Kordula
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewHickson
I recommend against rhetoric questions in answers. They risk being misunderstood as not an answer at all. You are trying to answer the question at the top of this page, aren't you? Otherwise please delete this post.Triplicate
Please phrase this as an explained conditional answer, in order to avoid the impression of asking a clarification question instead of answering (for which a comment should be used instead of an answer, compare meta.stackexchange.com/questions/214173/… ). For example like "If your problem is ... then the solution is to .... because .... ."Triplicate
T
0

You can understand what's going by adding 2 prints :

a.py :

print(__name__)
import b

b.py :

print(__name__)
import a

Then:

$ python3 a.py
__main__
b
a

so a.py ends up being loaded/executed 2 times. one as __main__ and one as a.

Thurstan answered 16/10, 2021 at 7:41 Comment(0)
P
0

In some cases it could be simply that the file is saved in the right directory but the python written on the file is not yet saved when writing it on the virtual environment. So when python imports a.py to b.py there is no code imported. It's blank in other terms. Seems like a easy to identify error that I see often. It's worth checking. -Cody

Pitfall answered 4/1, 2022 at 5:11 Comment(1)
Welcome to StackOverflow. I could see the situation you describe being a problem and causing the error message shown in the question, but it's not really relevant to this particular question, where the problem was with the circular imports.Eruptive
C
0

Let's see the problem and solution by example how the circular dependency arrives. I have a file window-data-generator.ipynb Main executing file Where the following two files are imported.

  1. escape.py
  2. MutationTypes.py

escape.py already have imported MutationTypes.py file Now, in window-data-generator.ipynb file I would like to execute the functionality of MutationTypes.py as below :

import escape as ESC
import MutationTypes
MutationTypes.SINGLE_RES_SUB 

The error prompts as AttributeErrorTraceback (most recent call last) /tmp/ipykernel_4340/4282764781.py in <module> ----> 1 MutationTypes.SINGLE_RES_SUB AttributeError: module 'MutationTypes' has no attribute 'SINGLE_RES_SUB'

How to solve this? As you already have MutationTypes file imported inside escape module, use MutationTypes file functionalities using escape module as below

ESC.MutationTypes.SINGLE_RES_SUB
Cero answered 2/6, 2022 at 1:10 Comment(0)
L
-1

Not sure how but the below change sorted my issue:

i was having the name of file and import name same for eg i had file name as emoji.py and i was trying to import emoji. But changing the name of file solved the issue .

Hope so it helps

Lietman answered 13/11, 2018 at 6:31 Comment(0)
D
-1

The order of the importing was the reason why I was having issues:

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

Just another example of how it might look, similar to RichieHindie's answer, but with classes.

Discobolus answered 25/11, 2019 at 20:1 Comment(0)
V
-1

I have crossed with this issue many times, but I didnt try to dig deeper about it. Now I understand the main issue.

This time my problem was importing Serializers ( django and restframework ) from different modules such as the following :

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

I was getting a problem like this :

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

What I wanted to accomplished was the following :

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

So, as mentioned by the lines above how to solve it ( top-level import ), I proceed to do the following changes :

# 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

Therefore, django runserver was executed without problems :

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

Final state of the code lines was the following :

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

Hope this could be helpful for everybody else.

Greetings,

Vampire answered 25/4, 2020 at 18:59 Comment(0)
N
-1

SoLvEd

Python is looking for the a object within your a.py module.

Either RENAME that file to something else or use

from __future__ import absolute_import 

at the top of your a.py module.

Nappie answered 6/10, 2020 at 13:32 Comment(0)
A
-2

In my case working with python 2.7 with numpy version 1.15.0, it worked with

pip install statsmodels=="0.10.0"
Alarice answered 23/6, 2020 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.