0

I have 2 python scripts. I am trying to access value of global variable from one.py into two.py.

Here is my code.

one.py

import two

myvar = False

def fun():
    global myvar
    myvar = True

two.use_me()

two.py

import one
print "from two: ", one.myvar
def use_me():
    print "This is used in one.py"

I am getting this error:

$ python two.py
from two: 
Traceback (most recent call last):
  File "two.py", line 1, in <module>
    import one
  File "one.py", line 1, in <module>
    import two
  File "two.py", line 2, in <module>
    print "from two: ", one.myvar
AttributeError: 'module' object has no attribute 'myvar'

Not sure what I am missing here. Can someone please help?

1
  • Removed the python 2.7 tag as this is not specific to 2.7. Commented Oct 4, 2018 at 19:51

1 Answer 1

4

You have a circular input. When you run two.py it executes import one which then executes import two. Now the import one returns immediately, the module object was already created, but it is empty! so on the next line you get an AttributeError.

That's what the traceback is telling you:

  • while running two.py's statement import one
  • while running one.py's statement import two
  • in file two.py I got an AttributeError executing print "two.py", one.myvar

Your one.py module does not need two at all so you should remove the import two statement.

Circular imports are generally a very strong sign that something is wrong in your design/architecture. Try to move functions/classes/variables around to avoid them, eventually combining the two modules.

There are ways to make them work but they are brittle and should be avoided.


If you have a function in two.py which needs stuff from one.py you should really move the function into one.py.

Yuo can also consider creating a three.py that imports both two.py and one.py.

How exactly you can break your circular import depends on the exact code you have so with just toy example we can continue for days in saying "you can just remove this" or "you can just move that". If you want a more precise answer we'd need to see very precise code that represents the definitions involved in the two modules.

Sign up to request clarification or add additional context in comments.

5 Comments

edited code to clear one point that I do need to import two as one.py uses couple of functions from two.py
That is sort of true. import one doesn't return immediately. It imports two which skips the import one statement since one is already imported. It then continues to execute all of two. Since at the point in one where import two is excuted, myvar doesnt exist, it throws this error. I dont recommend this, but moving the import line to the bottom of one.py "fixes" this error.
@npatel I believe you should simply not have that design. There are many ways to break circular dependencies but they depend on the exact code. Right now I'd say: just remove the print "two.py", one.myvar. Do the functions defined in two that you need in one depend on one and also on things defined in two? If not: just move them into one!
@Mateo I don't see how the description I give is different than that. The import is not "skipped" it succeeds because the module object is created immediately and immediately inserted into sys.modules. When I say import one returns immediately I mean that it returns the value it finds in sys.modules without re-executing one.py (and ending up in an infinite loop)
@npatel To be clear: if you can just move use_me into one.py you fixed your problem. If use_me uses two.f just move f into one.py. If f uses g just move g too into one.py. Keep doing this until you either end up with two.py not needing one.py anymore, or two.py completely empty.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.