Created
November 29, 2012 22:00
-
-
Save angusb/4172194 to your computer and use it in GitHub Desktop.
circular python imports
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# a.py | |
print '1a' | |
import b | |
print '2a' | |
x = b.x + 1 | |
# b.py | |
print '1b' | |
import a | |
print '2b' | |
x = 1 | |
""" | |
Rules for dealing with cyclical imports: | |
* 'import' and 'from x import y' are executable statements. They execute | |
when the program reaches their line. | |
* If a module is not in sys.modules, then an import creates a new entry | |
in sys.modules and 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 returns it, | |
regardless of whether the module has completed executing. This results | |
in modules which appear to be partly empty. | |
* The executing script runs in a module named __main__. Importing the | |
script under its own name will create a new module unrelated to __main__. | |
""" | |
# ./a.py | |
1a | |
# load b into sys.modules, run b | |
1b | |
# load a into sys.modules, run a | |
1a | |
# find b in sys.modules, return it | |
2a | |
# AttributeError: 'module' object has no attribute 'x' | |
# ./b.py | |
1b | |
# load a into sys.modules, run a | |
1a | |
# load b into sys.modules, run b | |
1b | |
# find a in sys.modules, return it | |
2b | |
x = 1 | |
2a | |
x = b.x + 1 | |
2b # See note below | |
x = 1 | |
# Note: the reason that the '2b' is printed again (and x = 1 is executed) | |
# is due to rule 2. It's at this point that control finally 'unwinds' to | |
# where module b first imports module a. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment