The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Python Programming
|
Circular import
Discuss Circular import in the Python Programming forum on Dev Shed. Circular import Python Programming forum discussing coding techniques, tips and tricks, and Zope related information. Python was designed from the ground up to be a completely object-oriented programming language.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

September 26th, 2012, 05:13 PM
|
|
Registered User
|
|
Join Date: Sep 2012
Posts: 5
Time spent in forums: 3 h 27 m 56 sec
Reputation Power: 0
|
|
|
Circular import
Is it allowed to have a circular import stucture, simplified with the example below?
Code:
# Module A:
import C
# Module B:
import A
# Module C:
import B
# Main :
import A
import B
import C
As I see it, it only requires an extra compilation of A. Is it wrong? What could happen if there are some circular imports? It is very hard, in my case, to get a good program structure that has no circular imports.
|

September 26th, 2012, 06:43 PM
|
 |
Contributing User
|
|
|
|
It appears that python recursively loads the modules.
Code:
$ ( cd /tmp && python -c 'import A' )
importing A line 1
importing C line 1
importing B line 1
finishing B import
finishing C import
finishing A import
$ ( cd /tmp && for a in A B C ; do echo $a.py && cat $a.py ; done )
A.py
print('importing A line 1')
import C
print('finishing A import')
B.py
print('importing B line 1')
import A
print('finishing B import')
C.py
print('importing C line 1')
import B
print('finishing C import')
$
Now, suppose I stick an error (not a syntax error) into A.
print('importing A line 1')
import C
1/0 # error
print('finishing A import')
Then it turns out that sys.modules contains entries for B and for C but not A .
Code:
$ ( cd /tmp && python -ic 'import sys,A' )
importing A line 1
importing C line 1
importing B line 1
finishing B import
finishing C import
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "A.py", line 3, in <module>
1/0 # error
ZeroDivisionError: integer division or modulo by zero
>>> print(sys.modules)
{'apt.os': None, ..., 'B': <module 'B' from 'B.pyc'>, ... }
Good luck.
__________________
[code] Code tags[/code] are essential for python code!
|

September 27th, 2012, 11:55 AM
|
|
Registered User
|
|
Join Date: Sep 2012
Posts: 5
Time spent in forums: 3 h 27 m 56 sec
Reputation Power: 0
|
|
|
Circular import, further testing
Thank you for your effort. This inspired me to do some own testing more ressembling my case. In the test there are 3 modules, A.py, B.py and C.py. They are called from main.py. The import structure is circular. The modules has one (or two) functions each, a(), b(), c() and c1(). There are print outs att the beginning of each module and when importing is finished. There are also print outs when each routine starts running and is finished.
Code:
# Module A.py
print 'start module A'
import C
print 'End import C in module A'
def a() :
print 'A.a() is running'
C.c1()
print 'In module A finish C.c1()'
# Module B.py
print 'start module B'
import A
print 'End import A in module B'
def b() :
print 'B.b() is running'
A.a()
print 'In module B finish B.b() and A.a()'
# Module C.py
print 'start module C'
import A
import B
print 'End import A, B in module C'
def c() :
print 'C.c() is running'
A.a()
B.b()
print 'In module C finish A.a() and B.b()'
def c1() :
print 'C.c1() is running'
# Module main.py
import sys
print 'start main'
import A
import B
import C
print 'End import A, B and C in module main'
if True :
print 'running main'
A.a()
B.b()
C.c()
print 'In module main finish A.a(), B.b() and C.c()'
# Finding the modules in 'sys.modules'
print
sys_modules = sys.modules
module_keys = sys_modules.keys()
for mod in module_keys :
if mod == 'A' or mod == 'B' or mod == 'C' or mod == '__main__' :
print mod, ':', sys_modules[ mod ]
### The print out from this code is :
start main
start module A
start module C
start module B
End import A in module B
End import A, B in module C
End import C in module A
End import A, B and C in module main
running main
A.a() is running
C.c1() is running
In module A finish C.c1()
B.b() is running
A.a() is running
C.c1() is running
In module A finish C.c1()
In module B finish B.b() and A.a()
C.c() is running
A.a() is running
C.c1() is running
In module A finish C.c1()
B.b() is running
A.a() is running
C.c1() is running
In module A finish C.c1()
In module B finish B.b() and A.a()
In module C finish A.a() and B.b()
In module main() finish A.a(), B.b() and C.c()
A : <module 'A' from '/Users/Sten/Programmering/Python/Train/Test import/A.pyc'>
B : <module 'B' from '/Users/Sten/Programmering/Python/Train/Test import/B.pyc'>
C : <module 'C' from '/Users/Sten/Programmering/Python/Train/Test import/C.pyc'>
__main__ : <module '__main__' (built-in)>
It seams to me that all works OK – any comments?
Thanks in advance
|

September 27th, 2012, 12:13 PM
|
 |
Contributing User
|
|
|
|
|
Spell "seams" as "seems".
More seriously, the test was fairly easy and we learned to "just try it". Actually, I was fairly sure beforehand, in fact rewrote my post after I tried it, that the circular import would work somewhat differently.
Last edited by b49P23TIvg : September 27th, 2012 at 12:15 PM.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|