Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # When are Python circular imports fatal?
- In your Python package, you have:
- - an `__init__.py` that designates this as a Python package
- - a `module_a.py`, containing a function `action_a()` that references an attribute (like a function or variable) in `module_b.py`, and
- - a `module_b.py`, containing a function `action_b()` that references an attribute (like a function or variable) in `module_a.py`.
- This situation can introduce a **circular import error**: `module_a` attempts to import `module_b`, but can't, because `module_b` needs to import `module_a`, which is in the process of being interpreted.
- But, sometimes Python is magic, and code that looks like it should cause this circular import error works just fine!
- When does it work and when does it not? *Why* does it work when it does?
- ## When it works
- ### Top of module; no `from`; Python 2 only
- Imports at top of module. `import MODULE`. Function references MODULE.ATTRIBUTE. Since `import MODULE` is an implicit relative import from the current directory, this might not work for importing from other packages. Since `import MODULE` is a **syntax error in Python 3** this **works in Python 2 only** so is not future-proof.
- # pkg/module_a.py # pkg/module_b.py
- import module_b import module_a
- def action_a(): def action_b():
- print(module_b.action_b.__name__) print(module_a.action_a.__name__)
- ### Top of module; no `from`; no relative
- Imports at top of module. `import PACKAGE.MODULE`. Function references PACKAGE.MODULE.ATTRIBUTE. Since `import .MODULE` is a syntax error, relative imports can't be used here; modules must know their containing package's name.
- # pkg/module_a.py # pkg/module_b.py
- import pkg.module_b import pkg.module_a
- def action_a(): def action_b():
- print(pkg.module_b.action_b.__name__) print(pkg.module_a.action_a.__name__)
- ### Bottom of module; import attribute, not module; `from` okay.
- Imports at bottom of module (or at least after referenced attribute). `from PACKAGE.MODULE import ATTRIBUTE`. May be relative, like `from .MODULE import ATTRIBUTE`. Function references ATTRIBUTE.
- # pkg/module_a.py # pkg/module_b.py
- def action_a(): def action_b():
- print(action_b.__name__) print(action_a.__name__)
- from .module_b import action_b from .module_a import action_a
- ### Top of function; `from` okay
- Imports at top of **function**. `from PACKAGE import MODULE`. PACKAGE may be relative, like `.`. Function references MODULE.ATTRIBUTE. This becomes ugly (but still works) if you have several functions that all refer to the same MODULE.
- # pkg/module_a.py # pkg/module_b.py
- def action_a(): def action_b():
- from . import module_b from . import module_a
- print(module_b.action_b.__name__) print(module_a.action_a.__name__)
Add Comment
Please, Sign In to add comment