Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 6.3 — Packages and __init__.py
Python · Example 2 of 3

A circular import, and the fix

First version: each module takes a name from the other, which fails. Second version: each imports the other *module* and uses it later inside a function. The split just keeps the printed message short and the same on every computer. try/except ImportError means: try the import, and if it fails with that error, print it instead of crashing (Topic 7.1).

A package is a folder of modules that you import as one unit. Its __init__.py runs on import and decides what the package shows to the outside, absolute imports name the full path from the top, relative imports use dots, and circular imports are fixed by changing who imports whom.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 5 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Create a package zoo: a folder zoo with an empty __init__.py, and a module zoo/cat.py that contains SOUND = "meow". Then write the code that imports cat from zoo and prints cat.SOUND.

02

Change the __init__.py of your zoo package so that SOUND is available directly. After your change, from zoo import SOUND must work.

03

Write the relative-import line that zoo/dog.py would use to import SOUND from its sibling cat.py.

Explain it without notes

01

What is a package, and what does __init__.py do?

02

What is the difference between absolute and relative imports? When does each fail?

03

What is __all__ for?

04

What causes a circular import error, and how do you fix it?

A circular import, and the fix
Sign in to run this example in your browser.

Expected output

ImportError: cannot import name 'a_value' from partially initialized module 'pkg.a'
fixed: AB BA