How i can solve this circular import? [duplicate] - python

In Python, what happens when two modules attempt to import each other? More generally, what happens if multiple modules attempt to import in a cycle?
See also What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"? for the common problem that may result, and advice on how to rewrite code to avoid such imports. See Why do circular imports seemingly work further up in the call stack but then raise an ImportError further down? for technical details on why and how the problem occurs.

If you do import foo (inside bar.py) and import bar (inside foo.py), it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.
The problem is when instead you do from foo import abc (inside bar.py) and from bar import xyz (inside foo.py). Because now each module requires the other module to already be imported (so that the name we are importing exists) before it can be imported.

There was a really good discussion on this over at comp.lang.python last year. It answers your question pretty thoroughly.
Imports are pretty straightforward really. Just remember the following:
'import' and 'from xxx import yyy' are executable statements. They execute
when the running program reaches that line.
If a module is not in sys.modules, then an import creates the new module
entry in sys.modules and then executes the code in the module. It does not
return control to the calling module until the execution has completed.
If a module does exist in sys.modules then an import simply returns that
module whether or not it has completed executing. That is the reason why
cyclic imports may return modules which appear to be partly empty.
Finally, the executing script runs in a module named __main__, importing
the script under its own name will create a new module unrelated to
__main__.
Take that lot together and you shouldn't get any surprises when importing
modules.

Cyclic imports terminate, but you need to be careful not to use the cyclically-imported modules during module initialization.
Consider the following files:
a.py:
print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"
b.py:
print "b in"
import a
print "b out"
x = 3
If you execute a.py, you'll get the following:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out
On the second import of b.py (in the second a in), the Python interpreter does not import b again, because it already exists in the module dict.
If you try to access b.x from a during module initialization, you will get an AttributeError.
Append the following line to a.py:
print b.x
Then, the output is:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
File "a.py", line 4, in <module>
import b
File "/home/shlomme/tmp/x/b.py", line 2, in <module>
import a
File "/home/shlomme/tmp/x/a.py", line 7, in <module>
print b.x
AttributeError: 'module' object has no attribute 'x'
This is because modules are executed on import and at the time b.x is accessed, the line x = 3 has not be executed yet, which will only happen after b out.

As other answers describe this pattern is acceptable in python:
def dostuff(self):
from foo import bar
...
Which will avoid the execution of the import statement when the file is imported by other modules. Only if there is a logical circular dependency, this will fail.
Most Circular Imports are not actually logical circular imports but rather raise ImportError errors, because of the way import() evaluates top level statements of the entire file when called.
These ImportErrors can almost always be avoided if you positively want your imports on top:
Consider this circular import:
App A
# profiles/serializers.py
from images.serializers import SimplifiedImageSerializer
class SimplifiedProfileSerializer(serializers.Serializer):
name = serializers.CharField()
class ProfileSerializer(SimplifiedProfileSerializer):
recent_images = SimplifiedImageSerializer(many=True)
App B
# images/serializers.py
from profiles.serializers import SimplifiedProfileSerializer
class SimplifiedImageSerializer(serializers.Serializer):
title = serializers.CharField()
class ImageSerializer(SimplifiedImageSerializer):
profile = SimplifiedProfileSerializer()
From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00, here is a way to deal with circular imports in python:
try:
from images.serializers import SimplifiedImageSerializer
except ImportError:
import sys
SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
This tries to import SimplifiedImageSerializer and if ImportError is raised, because it already is imported, it will pull it from the importcache.
PS: You have to read this entire post in David Beazley's voice.

To my surprise, no one has mentioned cyclic imports caused by type hints yet.
If you have cyclic imports only as a result of type hinting, they can be avoided in a clean manner.
Consider main.py which makes use of exceptions from another file:
from src.exceptions import SpecificException
class Foo:
def __init__(self, attrib: int):
self.attrib = attrib
raise SpecificException(Foo(5))
And the dedicated exception class exceptions.py:
from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo):
self.cause = cause
def __str__(self):
return f'Expected 3 but got {self.cause.attrib}.'
This will raise an ImportError since main.py imports exception.py and vice versa through Foo and SpecificException.
Because Foo is only required in exceptions.py during type checking, we can safely make its import conditional using the TYPE_CHECKING constant from the typing module. The constant is only True during type checking, which allows us to conditionally import Foo and thereby avoid the circular import error.
Something to note is that by doing so, Foo is not declared in exceptions.py at runtime, which leads to a NameError. To avoid that, we add from __future__ import annotations which transforms all type annotations in the module to strings.
Hence, we get the following code for Python 3.7+:
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo): # Foo becomes 'Foo' because of the future import
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.6, the future import does not exist, so Foo has to be a string:
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
​def __init__(self, cause: 'Foo'): # Foo has to be a string
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.5 and below, the type hinting functionality did not exist yet.
In future versions of Python, the annotations feature may become mandatory, after which the future import will no longer be necessary. Which version this will occur in is yet to be determined.
This answer is based on Yet another solution to dig you out of a circular import hole in Python by Stefaan Lippens.

Module a.py :
import b
print("This is from module a")
Module b.py
import a
print("This is from module b")
Running "Module a" will output:
>>>
'This is from module a'
'This is from module b'
'This is from module a'
>>>
It output this 3 lines while it was supposed to output infinitival because of circular importing.
What happens line by line while running"Module a" is listed here:
The first line is import b. so it will visit module b
The first line at module b is import a. so it will visit module a
The first line at module a is import b but note that this line won't be executed again anymore, because every file in python execute an import line just for once, it does not matter where or when it is executed. so it will pass to the next line and print "This is from module a".
After finish visiting whole module a from module b, we are still at module b. so the next line will print "This is from module b"
Module b lines are executed completely. so we will go back to module a where we started module b.
import b line have been executed already and won't be executed again. the next line will print "This is from module a" and program will be finished.

I got an example here that struck me!
foo.py
import bar
class gX(object):
g = 10
bar.py
from foo import gX
o = gX()
main.py
import foo
import bar
print "all done"
At the command line: $ python main.py
Traceback (most recent call last):
File "m.py", line 1, in <module>
import foo
File "/home/xolve/foo.py", line 1, in <module>
import bar
File "/home/xolve/bar.py", line 1, in <module>
from foo import gX
ImportError: cannot import name gX

There are a lot of great answers here. While there are usually quick solutions to the problem, some of which feel more pythonic than others, if you have the luxury of doing some refactoring, another approach is to analyze the organization of your code, and try to remove the circular dependency. You may find, for example, that you have:
File a.py
from b import B
class A:
#staticmethod
def save_result(result):
print('save the result')
#staticmethod
def do_something_a_ish(param):
A.save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
File b.py
from a import A
class B:
#staticmethod
def do_something_b_ish(param):
A.save_result(B.use_param_like_b_would(param))
In this case, just moving one static method to a separate file, say c.py:
File c.py
def save_result(result):
print('save the result')
will allow removing the save_result method from A, and thus allow removing the import of A from a in b:
Refactored File a.py
from b import B
from c import save_result
class A:
#staticmethod
def do_something_a_ish(param):
save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
Refactored File b.py
from c import save_result
class B:
#staticmethod
def do_something_b_ish(param):
save_result(B.use_param_like_b_would(param))
In summary, if you have a tool (e.g. pylint or PyCharm) that reports on methods that can be static, just throwing a staticmethod decorator on them might not be the best way to silence the warning. Even though the method seems related to the class, it might be better to separate it out, especially if you have several closely related modules that might need the same functionality and you intend to practice DRY principles.

I completely agree with pythoneer's answer here. But I have stumbled on some code that was flawed with circular imports and caused issues when trying to add unit tests. So to quickly patch it without changing everything you can resolve the issue by doing a dynamic import.
# Hack to import something without circular import issue
def load_module(name):
"""Load module using imp.find_module"""
names = name.split(".")
path = None
for name in names:
f, path, info = imp.find_module(name, path)
path = [path]
return imp.load_module(name, f, path[0], info)
constants = load_module("app.constants")
Again, this isn't a permanent fix but may help someone that wants to fix an import error without changing too much of the code.
Cheers!

Circular imports can be confusing because import does two things:
it executes imported module code
adds imported module to importing module global symbol table
The former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence it will not see objects created after import statement. Below code sample demonstrates it.
Circular imports are not the ultimate evil to be avoided at all cost. In some frameworks like Flask they are quite natural and tweaking your code to eliminate them does not make the code better.
main.py
print 'import b'
import b
print 'a in globals() {}'.format('a' in globals())
print 'import a'
import a
print 'a in globals() {}'.format('a' in globals())
if __name__ == '__main__':
print 'imports done'
print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)
b.by
print "b in, __name__ = {}".format(__name__)
x = 3
print 'b imports a'
import a
y = 5
print "b out"
a.py
print 'a in, __name__ = {}'.format(__name__)
print 'a imports b'
import b
print 'b has x {}'.format(hasattr(b, 'x'))
print 'b has y {}'.format(hasattr(b, 'y'))
print "a out"
python main.py output with comments
import b
b in, __name__ = b # b code execution started
b imports a
a in, __name__ = a # a code execution started
a imports b # b code execution is already in progress
b has x True
b has y False # b defines y after a import,
a out
b out
a in globals() False # import only adds a to main global symbol table
import a
a in globals() True
imports done
b has y True, a is b.a True # all b objects are available

Suppose you are running a test python file named request.py
In request.py, you write
import request
so this also most likely a circular import.
Solution:
Just change your test file to another name such as aaa.py, other than request.py.
Do not use names that are already used by other libs.

I solved the problem the following way, and it works well without any error.
Consider two files a.py and b.py.
I added this to a.py and it worked.
if __name__ == "__main__":
main ()
a.py:
import b
y = 2
def main():
print ("a out")
print (b.x)
if __name__ == "__main__":
main ()
b.py:
import a
print ("b out")
x = 3 + a.y
The output I get is
>>> b out
>>> a out
>>> 5

Ok, I think I have a pretty cool solution.
Let's say you have file a and file b.
You have a def or a class in file b that you want to use in module a, but you have something else, either a def, class, or variable from file a that you need in your definition or class in file b.
What you can do is, at the bottom of file a, after calling the function or class in file a that is needed in file b, but before calling the function or class from file b that you need for file a, say import b
Then, and here is the key part, in all of the definitions or classes in file b that need the def or class from file a (let's call it CLASS), you say from a import CLASS
This works because you can import file b without Python executing any of the import statements in file b, and thus you elude any circular imports.
For example:
File a:
class A(object):
def __init__(self, name):
self.name = name
CLASS = A("me")
import b
go = B(6)
go.dostuff
File b:
class B(object):
def __init__(self, number):
self.number = number
def dostuff(self):
from a import CLASS
print "Hello " + CLASS.name + ", " + str(number) + " is an interesting number."
Voila.

bar.py
print('going to import foo')
from foo import printx
foo.py
print('trying to import bar')
import bar
def printx():
print('x')
$ python bar.py
going to import foo
trying to import bar
going to import foo
Traceback (most recent call last):
File "bar.py", line 2, in <module>
from foo import printx
File "/home/suhail/Desktop/temp/circularimport/foo.py", line 2, in <module>
import bar
File "/home/suhail/Desktop/temp/circularimport/bar.py", line 2, in <module>
from foo import printx
ImportError: cannot import name 'printx' from partially initialized module 'foo' (most likely due to a circular import) (/home/suhail/Desktop/temp/circularimport/foo.py)

Related

Im getting a circular import error when I run my pygame. I believe I am importing everything correctly but it keeps giving me an issue [duplicate]

In Python, what happens when two modules attempt to import each other? More generally, what happens if multiple modules attempt to import in a cycle?
See also What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"? for the common problem that may result, and advice on how to rewrite code to avoid such imports. See Why do circular imports seemingly work further up in the call stack but then raise an ImportError further down? for technical details on why and how the problem occurs.
If you do import foo (inside bar.py) and import bar (inside foo.py), it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.
The problem is when instead you do from foo import abc (inside bar.py) and from bar import xyz (inside foo.py). Because now each module requires the other module to already be imported (so that the name we are importing exists) before it can be imported.
There was a really good discussion on this over at comp.lang.python last year. It answers your question pretty thoroughly.
Imports are pretty straightforward really. Just remember the following:
'import' and 'from xxx import yyy' are executable statements. They execute
when the running program reaches that line.
If a module is not in sys.modules, then an import creates the new module
entry in sys.modules and then executes the code in the module. It does not
return control to the calling module until the execution has completed.
If a module does exist in sys.modules then an import simply returns that
module whether or not it has completed executing. That is the reason why
cyclic imports may return modules which appear to be partly empty.
Finally, the executing script runs in a module named __main__, importing
the script under its own name will create a new module unrelated to
__main__.
Take that lot together and you shouldn't get any surprises when importing
modules.
Cyclic imports terminate, but you need to be careful not to use the cyclically-imported modules during module initialization.
Consider the following files:
a.py:
print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"
b.py:
print "b in"
import a
print "b out"
x = 3
If you execute a.py, you'll get the following:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out
On the second import of b.py (in the second a in), the Python interpreter does not import b again, because it already exists in the module dict.
If you try to access b.x from a during module initialization, you will get an AttributeError.
Append the following line to a.py:
print b.x
Then, the output is:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
File "a.py", line 4, in <module>
import b
File "/home/shlomme/tmp/x/b.py", line 2, in <module>
import a
File "/home/shlomme/tmp/x/a.py", line 7, in <module>
print b.x
AttributeError: 'module' object has no attribute 'x'
This is because modules are executed on import and at the time b.x is accessed, the line x = 3 has not be executed yet, which will only happen after b out.
As other answers describe this pattern is acceptable in python:
def dostuff(self):
from foo import bar
...
Which will avoid the execution of the import statement when the file is imported by other modules. Only if there is a logical circular dependency, this will fail.
Most Circular Imports are not actually logical circular imports but rather raise ImportError errors, because of the way import() evaluates top level statements of the entire file when called.
These ImportErrors can almost always be avoided if you positively want your imports on top:
Consider this circular import:
App A
# profiles/serializers.py
from images.serializers import SimplifiedImageSerializer
class SimplifiedProfileSerializer(serializers.Serializer):
name = serializers.CharField()
class ProfileSerializer(SimplifiedProfileSerializer):
recent_images = SimplifiedImageSerializer(many=True)
App B
# images/serializers.py
from profiles.serializers import SimplifiedProfileSerializer
class SimplifiedImageSerializer(serializers.Serializer):
title = serializers.CharField()
class ImageSerializer(SimplifiedImageSerializer):
profile = SimplifiedProfileSerializer()
From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00, here is a way to deal with circular imports in python:
try:
from images.serializers import SimplifiedImageSerializer
except ImportError:
import sys
SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
This tries to import SimplifiedImageSerializer and if ImportError is raised, because it already is imported, it will pull it from the importcache.
PS: You have to read this entire post in David Beazley's voice.
To my surprise, no one has mentioned cyclic imports caused by type hints yet.
If you have cyclic imports only as a result of type hinting, they can be avoided in a clean manner.
Consider main.py which makes use of exceptions from another file:
from src.exceptions import SpecificException
class Foo:
def __init__(self, attrib: int):
self.attrib = attrib
raise SpecificException(Foo(5))
And the dedicated exception class exceptions.py:
from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo):
self.cause = cause
def __str__(self):
return f'Expected 3 but got {self.cause.attrib}.'
This will raise an ImportError since main.py imports exception.py and vice versa through Foo and SpecificException.
Because Foo is only required in exceptions.py during type checking, we can safely make its import conditional using the TYPE_CHECKING constant from the typing module. The constant is only True during type checking, which allows us to conditionally import Foo and thereby avoid the circular import error.
Something to note is that by doing so, Foo is not declared in exceptions.py at runtime, which leads to a NameError. To avoid that, we add from __future__ import annotations which transforms all type annotations in the module to strings.
Hence, we get the following code for Python 3.7+:
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo): # Foo becomes 'Foo' because of the future import
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.6, the future import does not exist, so Foo has to be a string:
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
​def __init__(self, cause: 'Foo'): # Foo has to be a string
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.5 and below, the type hinting functionality did not exist yet.
In future versions of Python, the annotations feature may become mandatory, after which the future import will no longer be necessary. Which version this will occur in is yet to be determined.
This answer is based on Yet another solution to dig you out of a circular import hole in Python by Stefaan Lippens.
Module a.py :
import b
print("This is from module a")
Module b.py
import a
print("This is from module b")
Running "Module a" will output:
>>>
'This is from module a'
'This is from module b'
'This is from module a'
>>>
It output this 3 lines while it was supposed to output infinitival because of circular importing.
What happens line by line while running"Module a" is listed here:
The first line is import b. so it will visit module b
The first line at module b is import a. so it will visit module a
The first line at module a is import b but note that this line won't be executed again anymore, because every file in python execute an import line just for once, it does not matter where or when it is executed. so it will pass to the next line and print "This is from module a".
After finish visiting whole module a from module b, we are still at module b. so the next line will print "This is from module b"
Module b lines are executed completely. so we will go back to module a where we started module b.
import b line have been executed already and won't be executed again. the next line will print "This is from module a" and program will be finished.
I got an example here that struck me!
foo.py
import bar
class gX(object):
g = 10
bar.py
from foo import gX
o = gX()
main.py
import foo
import bar
print "all done"
At the command line: $ python main.py
Traceback (most recent call last):
File "m.py", line 1, in <module>
import foo
File "/home/xolve/foo.py", line 1, in <module>
import bar
File "/home/xolve/bar.py", line 1, in <module>
from foo import gX
ImportError: cannot import name gX
There are a lot of great answers here. While there are usually quick solutions to the problem, some of which feel more pythonic than others, if you have the luxury of doing some refactoring, another approach is to analyze the organization of your code, and try to remove the circular dependency. You may find, for example, that you have:
File a.py
from b import B
class A:
#staticmethod
def save_result(result):
print('save the result')
#staticmethod
def do_something_a_ish(param):
A.save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
File b.py
from a import A
class B:
#staticmethod
def do_something_b_ish(param):
A.save_result(B.use_param_like_b_would(param))
In this case, just moving one static method to a separate file, say c.py:
File c.py
def save_result(result):
print('save the result')
will allow removing the save_result method from A, and thus allow removing the import of A from a in b:
Refactored File a.py
from b import B
from c import save_result
class A:
#staticmethod
def do_something_a_ish(param):
save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
Refactored File b.py
from c import save_result
class B:
#staticmethod
def do_something_b_ish(param):
save_result(B.use_param_like_b_would(param))
In summary, if you have a tool (e.g. pylint or PyCharm) that reports on methods that can be static, just throwing a staticmethod decorator on them might not be the best way to silence the warning. Even though the method seems related to the class, it might be better to separate it out, especially if you have several closely related modules that might need the same functionality and you intend to practice DRY principles.
I completely agree with pythoneer's answer here. But I have stumbled on some code that was flawed with circular imports and caused issues when trying to add unit tests. So to quickly patch it without changing everything you can resolve the issue by doing a dynamic import.
# Hack to import something without circular import issue
def load_module(name):
"""Load module using imp.find_module"""
names = name.split(".")
path = None
for name in names:
f, path, info = imp.find_module(name, path)
path = [path]
return imp.load_module(name, f, path[0], info)
constants = load_module("app.constants")
Again, this isn't a permanent fix but may help someone that wants to fix an import error without changing too much of the code.
Cheers!
Circular imports can be confusing because import does two things:
it executes imported module code
adds imported module to importing module global symbol table
The former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence it will not see objects created after import statement. Below code sample demonstrates it.
Circular imports are not the ultimate evil to be avoided at all cost. In some frameworks like Flask they are quite natural and tweaking your code to eliminate them does not make the code better.
main.py
print 'import b'
import b
print 'a in globals() {}'.format('a' in globals())
print 'import a'
import a
print 'a in globals() {}'.format('a' in globals())
if __name__ == '__main__':
print 'imports done'
print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)
b.by
print "b in, __name__ = {}".format(__name__)
x = 3
print 'b imports a'
import a
y = 5
print "b out"
a.py
print 'a in, __name__ = {}'.format(__name__)
print 'a imports b'
import b
print 'b has x {}'.format(hasattr(b, 'x'))
print 'b has y {}'.format(hasattr(b, 'y'))
print "a out"
python main.py output with comments
import b
b in, __name__ = b # b code execution started
b imports a
a in, __name__ = a # a code execution started
a imports b # b code execution is already in progress
b has x True
b has y False # b defines y after a import,
a out
b out
a in globals() False # import only adds a to main global symbol table
import a
a in globals() True
imports done
b has y True, a is b.a True # all b objects are available
Suppose you are running a test python file named request.py
In request.py, you write
import request
so this also most likely a circular import.
Solution:
Just change your test file to another name such as aaa.py, other than request.py.
Do not use names that are already used by other libs.
I solved the problem the following way, and it works well without any error.
Consider two files a.py and b.py.
I added this to a.py and it worked.
if __name__ == "__main__":
main ()
a.py:
import b
y = 2
def main():
print ("a out")
print (b.x)
if __name__ == "__main__":
main ()
b.py:
import a
print ("b out")
x = 3 + a.y
The output I get is
>>> b out
>>> a out
>>> 5
Ok, I think I have a pretty cool solution.
Let's say you have file a and file b.
You have a def or a class in file b that you want to use in module a, but you have something else, either a def, class, or variable from file a that you need in your definition or class in file b.
What you can do is, at the bottom of file a, after calling the function or class in file a that is needed in file b, but before calling the function or class from file b that you need for file a, say import b
Then, and here is the key part, in all of the definitions or classes in file b that need the def or class from file a (let's call it CLASS), you say from a import CLASS
This works because you can import file b without Python executing any of the import statements in file b, and thus you elude any circular imports.
For example:
File a:
class A(object):
def __init__(self, name):
self.name = name
CLASS = A("me")
import b
go = B(6)
go.dostuff
File b:
class B(object):
def __init__(self, number):
self.number = number
def dostuff(self):
from a import CLASS
print "Hello " + CLASS.name + ", " + str(number) + " is an interesting number."
Voila.
bar.py
print('going to import foo')
from foo import printx
foo.py
print('trying to import bar')
import bar
def printx():
print('x')
$ python bar.py
going to import foo
trying to import bar
going to import foo
Traceback (most recent call last):
File "bar.py", line 2, in <module>
from foo import printx
File "/home/suhail/Desktop/temp/circularimport/foo.py", line 2, in <module>
import bar
File "/home/suhail/Desktop/temp/circularimport/bar.py", line 2, in <module>
from foo import printx
ImportError: cannot import name 'printx' from partially initialized module 'foo' (most likely due to a circular import) (/home/suhail/Desktop/temp/circularimport/foo.py)

python create and register module via compile function [duplicate]

I have some code in the form of a string and would like to make a module out of it without writing to disk.
When I try using imp and a StringIO object to do this, I get:
>>> imp.load_source('my_module', '', StringIO('print "hello world"'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: load_source() argument 3 must be file, not instance
>>> imp.load_module('my_module', StringIO('print "hello world"'), '', ('', '', 0))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: load_module arg#2 should be a file or None
How can I create the module without having an actual file? Alternatively, how can I wrap a StringIO in a file without writing to disk?
UPDATE:
NOTE: This issue is also a problem in python3.
The code I'm trying to load is only partially trusted. I've gone through it with ast and determined that it doesn't import anything or do anything I don't like, but I don't trust it enough to run it when I have local variables running around that could get modified, and I don't trust my own code to stay out of the way of the code I'm trying to import.
I created an empty module that only contains the following:
def load(code):
# Delete all local variables
globals()['code'] = code
del locals()['code']
# Run the code
exec(globals()['code'])
# Delete any global variables we've added
del globals()['load']
del globals()['code']
# Copy k so we can use it
if 'k' in locals():
globals()['k'] = locals()['k']
del locals()['k']
# Copy the rest of the variables
for k in locals().keys():
globals()[k] = locals()[k]
Then you can import mymodule and call mymodule.load(code). This works for me because I've ensured that the code I'm loading does not use globals. Also, the global keyword is only a parser directive and can't refer to anything outside of the exec.
This really is way too much work to import the module without writing to disk, but if you ever want to do this, I believe it's the best way.
Here is how to import a string as a module (Python 2.x):
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec my_code in mymodule.__dict__
In Python 3, exec is a function, so this should work:
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec(my_code, mymodule.__dict__)
Now access the module attributes (and functions, classes etc) as:
print(mymodule.a)
>>> 5
To ignore any next attempt to import, add the module to sys:
sys.modules['mymodule'] = mymodule
imp.new_module is deprecated since python 3.4, but it still works as of python 3.9
imp.new_module was replaced with importlib.util.module_from_spec
importlib.util.module_from_spec
is preferred over using types.ModuleType to create a new module as
spec is used to set as many import-controlled attributes on the module
as possible.
importlib.util.spec_from_loader
uses available loader APIs, such as InspectLoader.is_package(), to
fill in any missing information on the spec.
these module attributes are __builtins__ __doc__ __loader__ __name__ __package__ __spec__
import sys, importlib.util
def import_module_from_string(name: str, source: str):
"""
Import module from source string.
Example use:
import_module_from_string("m", "f = lambda: print('hello')")
m.f()
"""
spec = importlib.util.spec_from_loader(name, loader=None)
module = importlib.util.module_from_spec(spec)
exec(source, module.__dict__)
sys.modules[name] = module
globals()[name] = module
# demo
# note: "if True:" allows to indent the source string
import_module_from_string('hello_module', '''if True:
def hello():
print('hello')
''')
hello_module.hello()
You could simply create a Module object and stuff it into sys.modules and put your code inside.
Something like:
import sys
from types import ModuleType
mod = ModuleType('mymodule')
sys.modules['mymodule'] = mod
exec(mycode, mod.__dict__)
If the code for the module is in a string, you can forgo using StringIO and use it directly with exec, as illustrated below with a file named dynmodule.py.
Works in Python 2 & 3.
from __future__ import print_function
class _DynamicModule(object):
def load(self, code):
execdict = {'__builtins__': None} # optional, to increase safety
exec(code, execdict)
keys = execdict.get(
'__all__', # use __all__ attribute if defined
# else all non-private attributes
(key for key in execdict if not key.startswith('_')))
for key in keys:
setattr(self, key, execdict[key])
# replace this module object in sys.modules with empty _DynamicModule instance
# see Stack Overflow question:
# https://stackoverflow.com/questions/5365562/why-is-the-value-of-name-changing-after-assignment-to-sys-modules-name
import sys as _sys
_ref, _sys.modules[__name__] = _sys.modules[__name__], _DynamicModule()
if __name__ == '__main__':
import dynmodule # name of this module
import textwrap # for more readable code formatting in sample string
# string to be loaded can come from anywhere or be generated on-the-fly
module_code = textwrap.dedent("""\
foo, bar, baz = 5, 8, 2
def func():
return foo*bar + baz
__all__ = 'foo', 'bar', 'func' # 'baz' not included
""")
dynmodule.load(module_code) # defines module's contents
print('dynmodule.foo:', dynmodule.foo)
try:
print('dynmodule.baz:', dynmodule.baz)
except AttributeError:
print('no dynmodule.baz attribute was defined')
else:
print('Error: there should be no dynmodule.baz module attribute')
print('dynmodule.func() returned:', dynmodule.func())
Output:
dynmodule.foo: 5
no dynmodule.baz attribute was defined
dynmodule.func() returned: 42
Setting the '__builtins__' entry to None in the execdict dictionary prevents the code from directly executing any built-in functions, like __import__, and so makes running it safer. You can ease that restriction by selectively adding things to it you feel are OK and/or required.
It's also possible to add your own predefined utilities and attributes which you'd like made available to the code thereby creating a custom execution context for it to run in. That sort of thing can be useful for implementing a "plug-in" or other user-extensible architecture.
you could use exec or eval to execute python code as a string. see here, here and here
The documentation for imp.load_source says (my emphasis):
The file argument is the source file, open for reading as text, from the beginning. It must currently be a real file object, not a user-defined class emulating a file.
... so you may be out of luck with this method, I'm afraid.
Perhaps eval would be enough for you in this case?
This sounds like a rather surprising requirement, though - it might help if you add some more to your question about the problem you're really trying to solve.

How can a string be imported as a Python module bound to a local name? [duplicate]

I have some code in the form of a string and would like to make a module out of it without writing to disk.
When I try using imp and a StringIO object to do this, I get:
>>> imp.load_source('my_module', '', StringIO('print "hello world"'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: load_source() argument 3 must be file, not instance
>>> imp.load_module('my_module', StringIO('print "hello world"'), '', ('', '', 0))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: load_module arg#2 should be a file or None
How can I create the module without having an actual file? Alternatively, how can I wrap a StringIO in a file without writing to disk?
UPDATE:
NOTE: This issue is also a problem in python3.
The code I'm trying to load is only partially trusted. I've gone through it with ast and determined that it doesn't import anything or do anything I don't like, but I don't trust it enough to run it when I have local variables running around that could get modified, and I don't trust my own code to stay out of the way of the code I'm trying to import.
I created an empty module that only contains the following:
def load(code):
# Delete all local variables
globals()['code'] = code
del locals()['code']
# Run the code
exec(globals()['code'])
# Delete any global variables we've added
del globals()['load']
del globals()['code']
# Copy k so we can use it
if 'k' in locals():
globals()['k'] = locals()['k']
del locals()['k']
# Copy the rest of the variables
for k in locals().keys():
globals()[k] = locals()[k]
Then you can import mymodule and call mymodule.load(code). This works for me because I've ensured that the code I'm loading does not use globals. Also, the global keyword is only a parser directive and can't refer to anything outside of the exec.
This really is way too much work to import the module without writing to disk, but if you ever want to do this, I believe it's the best way.
Here is how to import a string as a module (Python 2.x):
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec my_code in mymodule.__dict__
In Python 3, exec is a function, so this should work:
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec(my_code, mymodule.__dict__)
Now access the module attributes (and functions, classes etc) as:
print(mymodule.a)
>>> 5
To ignore any next attempt to import, add the module to sys:
sys.modules['mymodule'] = mymodule
imp.new_module is deprecated since python 3.4, but it still works as of python 3.9
imp.new_module was replaced with importlib.util.module_from_spec
importlib.util.module_from_spec
is preferred over using types.ModuleType to create a new module as
spec is used to set as many import-controlled attributes on the module
as possible.
importlib.util.spec_from_loader
uses available loader APIs, such as InspectLoader.is_package(), to
fill in any missing information on the spec.
these module attributes are __builtins__ __doc__ __loader__ __name__ __package__ __spec__
import sys, importlib.util
def import_module_from_string(name: str, source: str):
"""
Import module from source string.
Example use:
import_module_from_string("m", "f = lambda: print('hello')")
m.f()
"""
spec = importlib.util.spec_from_loader(name, loader=None)
module = importlib.util.module_from_spec(spec)
exec(source, module.__dict__)
sys.modules[name] = module
globals()[name] = module
# demo
# note: "if True:" allows to indent the source string
import_module_from_string('hello_module', '''if True:
def hello():
print('hello')
''')
hello_module.hello()
You could simply create a Module object and stuff it into sys.modules and put your code inside.
Something like:
import sys
from types import ModuleType
mod = ModuleType('mymodule')
sys.modules['mymodule'] = mod
exec(mycode, mod.__dict__)
If the code for the module is in a string, you can forgo using StringIO and use it directly with exec, as illustrated below with a file named dynmodule.py.
Works in Python 2 & 3.
from __future__ import print_function
class _DynamicModule(object):
def load(self, code):
execdict = {'__builtins__': None} # optional, to increase safety
exec(code, execdict)
keys = execdict.get(
'__all__', # use __all__ attribute if defined
# else all non-private attributes
(key for key in execdict if not key.startswith('_')))
for key in keys:
setattr(self, key, execdict[key])
# replace this module object in sys.modules with empty _DynamicModule instance
# see Stack Overflow question:
# https://stackoverflow.com/questions/5365562/why-is-the-value-of-name-changing-after-assignment-to-sys-modules-name
import sys as _sys
_ref, _sys.modules[__name__] = _sys.modules[__name__], _DynamicModule()
if __name__ == '__main__':
import dynmodule # name of this module
import textwrap # for more readable code formatting in sample string
# string to be loaded can come from anywhere or be generated on-the-fly
module_code = textwrap.dedent("""\
foo, bar, baz = 5, 8, 2
def func():
return foo*bar + baz
__all__ = 'foo', 'bar', 'func' # 'baz' not included
""")
dynmodule.load(module_code) # defines module's contents
print('dynmodule.foo:', dynmodule.foo)
try:
print('dynmodule.baz:', dynmodule.baz)
except AttributeError:
print('no dynmodule.baz attribute was defined')
else:
print('Error: there should be no dynmodule.baz module attribute')
print('dynmodule.func() returned:', dynmodule.func())
Output:
dynmodule.foo: 5
no dynmodule.baz attribute was defined
dynmodule.func() returned: 42
Setting the '__builtins__' entry to None in the execdict dictionary prevents the code from directly executing any built-in functions, like __import__, and so makes running it safer. You can ease that restriction by selectively adding things to it you feel are OK and/or required.
It's also possible to add your own predefined utilities and attributes which you'd like made available to the code thereby creating a custom execution context for it to run in. That sort of thing can be useful for implementing a "plug-in" or other user-extensible architecture.
you could use exec or eval to execute python code as a string. see here, here and here
The documentation for imp.load_source says (my emphasis):
The file argument is the source file, open for reading as text, from the beginning. It must currently be a real file object, not a user-defined class emulating a file.
... so you may be out of luck with this method, I'm afraid.
Perhaps eval would be enough for you in this case?
This sounds like a rather surprising requirement, though - it might help if you add some more to your question about the problem you're really trying to solve.

Python Cant find attribute in module and strange behavior

Ok lets say I have 3 files, we will call them a,b,c. I am using sublime to run and build these scripts.
a imports and uses method from b
b imports and uses method from c
c imports and uses method from a
With ctrl+b Sublime 2 will build and run my code.
Build with a tab active ==>
Error: module b has no attribute 'x'
Build with b tab active ==>
Error: Module c has no attribute 'y'
Build with c tab active ==>
Success
Is this an issue with Sublime specific or a problem with my code.
There's a tricky corner case in Python when doing circular imports. If you use the "import ..." form of the import statement, like this:
# a.py
import b
def method_a():
print "Method A called"
def call_b_from_a():
b.method_b()
# b.py
import c
def method_b():
print "Method B called"
def call_c_from_b():
c.method_c()
# c.py
import a
def method_c():
print "Method C called"
def call_a_from_c():
a.method_a()
Then you can do something like this:
>>> import a
>>> a.call_b_from_a()
Method B called
and similarly for b and c; in short, everything just works. However, if you use the "from ... import ..." form of the import statement, like this:
# a.py
from b import method_b
def method_a():
print "Method A called"
def call_b_from_a():
method_b()
# b.py
from c import method_c
def method_b():
print "Method B called"
def call_c_from_b():
method_c()
# c.py
from a import method_a
def method_c():
print "Method C called"
def call_a_from_c():
method_a()
Then you get errors like this:
>>> import a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 2, in <module>
from b import method_b
File "b.py", line 2, in <module>
from c import method_c
File "c.py", line 2, in <module>
from a import method_a
ImportError: cannot import name method_a
In short, circular imports can be used, but they do pose some corner cases. Without actually seeing your code, I would guess it's probably something related to that.
For future reference, you'll almost always get better answers if you post the actual code you're using.

What happens when using mutual or circular (cyclic) imports?

In Python, what happens when two modules attempt to import each other? More generally, what happens if multiple modules attempt to import in a cycle?
See also What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"? for the common problem that may result, and advice on how to rewrite code to avoid such imports. See Why do circular imports seemingly work further up in the call stack but then raise an ImportError further down? for technical details on why and how the problem occurs.
If you do import foo (inside bar.py) and import bar (inside foo.py), it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.
The problem is when instead you do from foo import abc (inside bar.py) and from bar import xyz (inside foo.py). Because now each module requires the other module to already be imported (so that the name we are importing exists) before it can be imported.
There was a really good discussion on this over at comp.lang.python last year. It answers your question pretty thoroughly.
Imports are pretty straightforward really. Just remember the following:
'import' and 'from xxx import yyy' are executable statements. They execute
when the running program reaches that line.
If a module is not in sys.modules, then an import creates the new module
entry in sys.modules and then executes the code in the module. It does not
return control to the calling module until the execution has completed.
If a module does exist in sys.modules then an import simply returns that
module whether or not it has completed executing. That is the reason why
cyclic imports may return modules which appear to be partly empty.
Finally, the executing script runs in a module named __main__, importing
the script under its own name will create a new module unrelated to
__main__.
Take that lot together and you shouldn't get any surprises when importing
modules.
Cyclic imports terminate, but you need to be careful not to use the cyclically-imported modules during module initialization.
Consider the following files:
a.py:
print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"
b.py:
print "b in"
import a
print "b out"
x = 3
If you execute a.py, you'll get the following:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out
On the second import of b.py (in the second a in), the Python interpreter does not import b again, because it already exists in the module dict.
If you try to access b.x from a during module initialization, you will get an AttributeError.
Append the following line to a.py:
print b.x
Then, the output is:
$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
File "a.py", line 4, in <module>
import b
File "/home/shlomme/tmp/x/b.py", line 2, in <module>
import a
File "/home/shlomme/tmp/x/a.py", line 7, in <module>
print b.x
AttributeError: 'module' object has no attribute 'x'
This is because modules are executed on import and at the time b.x is accessed, the line x = 3 has not be executed yet, which will only happen after b out.
As other answers describe this pattern is acceptable in python:
def dostuff(self):
from foo import bar
...
Which will avoid the execution of the import statement when the file is imported by other modules. Only if there is a logical circular dependency, this will fail.
Most Circular Imports are not actually logical circular imports but rather raise ImportError errors, because of the way import() evaluates top level statements of the entire file when called.
These ImportErrors can almost always be avoided if you positively want your imports on top:
Consider this circular import:
App A
# profiles/serializers.py
from images.serializers import SimplifiedImageSerializer
class SimplifiedProfileSerializer(serializers.Serializer):
name = serializers.CharField()
class ProfileSerializer(SimplifiedProfileSerializer):
recent_images = SimplifiedImageSerializer(many=True)
App B
# images/serializers.py
from profiles.serializers import SimplifiedProfileSerializer
class SimplifiedImageSerializer(serializers.Serializer):
title = serializers.CharField()
class ImageSerializer(SimplifiedImageSerializer):
profile = SimplifiedProfileSerializer()
From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00, here is a way to deal with circular imports in python:
try:
from images.serializers import SimplifiedImageSerializer
except ImportError:
import sys
SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
This tries to import SimplifiedImageSerializer and if ImportError is raised, because it already is imported, it will pull it from the importcache.
PS: You have to read this entire post in David Beazley's voice.
To my surprise, no one has mentioned cyclic imports caused by type hints yet.
If you have cyclic imports only as a result of type hinting, they can be avoided in a clean manner.
Consider main.py which makes use of exceptions from another file:
from src.exceptions import SpecificException
class Foo:
def __init__(self, attrib: int):
self.attrib = attrib
raise SpecificException(Foo(5))
And the dedicated exception class exceptions.py:
from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo):
self.cause = cause
def __str__(self):
return f'Expected 3 but got {self.cause.attrib}.'
This will raise an ImportError since main.py imports exception.py and vice versa through Foo and SpecificException.
Because Foo is only required in exceptions.py during type checking, we can safely make its import conditional using the TYPE_CHECKING constant from the typing module. The constant is only True during type checking, which allows us to conditionally import Foo and thereby avoid the circular import error.
Something to note is that by doing so, Foo is not declared in exceptions.py at runtime, which leads to a NameError. To avoid that, we add from __future__ import annotations which transforms all type annotations in the module to strings.
Hence, we get the following code for Python 3.7+:
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
def __init__(self, cause: Foo): # Foo becomes 'Foo' because of the future import
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.6, the future import does not exist, so Foo has to be a string:
from typing import TYPE_CHECKING
if TYPE_CHECKING: # Only imports the below statements during type checking
​from src.main import Foo
class SpecificException(Exception):
​def __init__(self, cause: 'Foo'): # Foo has to be a string
​self.cause = cause
​def __str__(self):
​return f'Expected 3 but got {self.cause.attrib}.'
In Python 3.5 and below, the type hinting functionality did not exist yet.
In future versions of Python, the annotations feature may become mandatory, after which the future import will no longer be necessary. Which version this will occur in is yet to be determined.
This answer is based on Yet another solution to dig you out of a circular import hole in Python by Stefaan Lippens.
Module a.py :
import b
print("This is from module a")
Module b.py
import a
print("This is from module b")
Running "Module a" will output:
>>>
'This is from module a'
'This is from module b'
'This is from module a'
>>>
It output this 3 lines while it was supposed to output infinitival because of circular importing.
What happens line by line while running"Module a" is listed here:
The first line is import b. so it will visit module b
The first line at module b is import a. so it will visit module a
The first line at module a is import b but note that this line won't be executed again anymore, because every file in python execute an import line just for once, it does not matter where or when it is executed. so it will pass to the next line and print "This is from module a".
After finish visiting whole module a from module b, we are still at module b. so the next line will print "This is from module b"
Module b lines are executed completely. so we will go back to module a where we started module b.
import b line have been executed already and won't be executed again. the next line will print "This is from module a" and program will be finished.
I got an example here that struck me!
foo.py
import bar
class gX(object):
g = 10
bar.py
from foo import gX
o = gX()
main.py
import foo
import bar
print "all done"
At the command line: $ python main.py
Traceback (most recent call last):
File "m.py", line 1, in <module>
import foo
File "/home/xolve/foo.py", line 1, in <module>
import bar
File "/home/xolve/bar.py", line 1, in <module>
from foo import gX
ImportError: cannot import name gX
There are a lot of great answers here. While there are usually quick solutions to the problem, some of which feel more pythonic than others, if you have the luxury of doing some refactoring, another approach is to analyze the organization of your code, and try to remove the circular dependency. You may find, for example, that you have:
File a.py
from b import B
class A:
#staticmethod
def save_result(result):
print('save the result')
#staticmethod
def do_something_a_ish(param):
A.save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
File b.py
from a import A
class B:
#staticmethod
def do_something_b_ish(param):
A.save_result(B.use_param_like_b_would(param))
In this case, just moving one static method to a separate file, say c.py:
File c.py
def save_result(result):
print('save the result')
will allow removing the save_result method from A, and thus allow removing the import of A from a in b:
Refactored File a.py
from b import B
from c import save_result
class A:
#staticmethod
def do_something_a_ish(param):
save_result(A.use_param_like_a_would(param))
#staticmethod
def do_something_related_to_b(param):
B.do_something_b_ish(param)
Refactored File b.py
from c import save_result
class B:
#staticmethod
def do_something_b_ish(param):
save_result(B.use_param_like_b_would(param))
In summary, if you have a tool (e.g. pylint or PyCharm) that reports on methods that can be static, just throwing a staticmethod decorator on them might not be the best way to silence the warning. Even though the method seems related to the class, it might be better to separate it out, especially if you have several closely related modules that might need the same functionality and you intend to practice DRY principles.
I completely agree with pythoneer's answer here. But I have stumbled on some code that was flawed with circular imports and caused issues when trying to add unit tests. So to quickly patch it without changing everything you can resolve the issue by doing a dynamic import.
# Hack to import something without circular import issue
def load_module(name):
"""Load module using imp.find_module"""
names = name.split(".")
path = None
for name in names:
f, path, info = imp.find_module(name, path)
path = [path]
return imp.load_module(name, f, path[0], info)
constants = load_module("app.constants")
Again, this isn't a permanent fix but may help someone that wants to fix an import error without changing too much of the code.
Cheers!
Circular imports can be confusing because import does two things:
it executes imported module code
adds imported module to importing module global symbol table
The former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence it will not see objects created after import statement. Below code sample demonstrates it.
Circular imports are not the ultimate evil to be avoided at all cost. In some frameworks like Flask they are quite natural and tweaking your code to eliminate them does not make the code better.
main.py
print 'import b'
import b
print 'a in globals() {}'.format('a' in globals())
print 'import a'
import a
print 'a in globals() {}'.format('a' in globals())
if __name__ == '__main__':
print 'imports done'
print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)
b.by
print "b in, __name__ = {}".format(__name__)
x = 3
print 'b imports a'
import a
y = 5
print "b out"
a.py
print 'a in, __name__ = {}'.format(__name__)
print 'a imports b'
import b
print 'b has x {}'.format(hasattr(b, 'x'))
print 'b has y {}'.format(hasattr(b, 'y'))
print "a out"
python main.py output with comments
import b
b in, __name__ = b # b code execution started
b imports a
a in, __name__ = a # a code execution started
a imports b # b code execution is already in progress
b has x True
b has y False # b defines y after a import,
a out
b out
a in globals() False # import only adds a to main global symbol table
import a
a in globals() True
imports done
b has y True, a is b.a True # all b objects are available
Suppose you are running a test python file named request.py
In request.py, you write
import request
so this also most likely a circular import.
Solution:
Just change your test file to another name such as aaa.py, other than request.py.
Do not use names that are already used by other libs.
I solved the problem the following way, and it works well without any error.
Consider two files a.py and b.py.
I added this to a.py and it worked.
if __name__ == "__main__":
main ()
a.py:
import b
y = 2
def main():
print ("a out")
print (b.x)
if __name__ == "__main__":
main ()
b.py:
import a
print ("b out")
x = 3 + a.y
The output I get is
>>> b out
>>> a out
>>> 5
Ok, I think I have a pretty cool solution.
Let's say you have file a and file b.
You have a def or a class in file b that you want to use in module a, but you have something else, either a def, class, or variable from file a that you need in your definition or class in file b.
What you can do is, at the bottom of file a, after calling the function or class in file a that is needed in file b, but before calling the function or class from file b that you need for file a, say import b
Then, and here is the key part, in all of the definitions or classes in file b that need the def or class from file a (let's call it CLASS), you say from a import CLASS
This works because you can import file b without Python executing any of the import statements in file b, and thus you elude any circular imports.
For example:
File a:
class A(object):
def __init__(self, name):
self.name = name
CLASS = A("me")
import b
go = B(6)
go.dostuff
File b:
class B(object):
def __init__(self, number):
self.number = number
def dostuff(self):
from a import CLASS
print "Hello " + CLASS.name + ", " + str(number) + " is an interesting number."
Voila.
bar.py
print('going to import foo')
from foo import printx
foo.py
print('trying to import bar')
import bar
def printx():
print('x')
$ python bar.py
going to import foo
trying to import bar
going to import foo
Traceback (most recent call last):
File "bar.py", line 2, in <module>
from foo import printx
File "/home/suhail/Desktop/temp/circularimport/foo.py", line 2, in <module>
import bar
File "/home/suhail/Desktop/temp/circularimport/bar.py", line 2, in <module>
from foo import printx
ImportError: cannot import name 'printx' from partially initialized module 'foo' (most likely due to a circular import) (/home/suhail/Desktop/temp/circularimport/foo.py)

Categories

Resources