Lesson 14 of 21 · 50 min · UG / professional
Packages, __init__, relative imports
A folder of modules with a public name is a package. __init__ runs when the package is imported. Relative imports (from . import fees) are for inside that folder — easy to get wrong, so we name the rule.
Application blueprint
A program is folders, config and a main door.
You will be able to
- ✓ See a package as a named folder of modules, not fifty loose files
- ✓ Know __init__.py runs when the package is imported
- ✓ Treat relative imports (from . import fees) as an inside-the-folder rule
A folder with a public name is a package
rsil_fees/ with late.py and gst.py is a package when the project treats that folder as one importable name. On a laptop, import rsil_fees looks for rsil_fees/__init__.py (in modern Python the file can be empty, but the folder still needs to be a package on the path). __init__.py runs at import time — so it must be as quiet as any module. It may re-export late_fee so callers write from rsil_fees import late_fee.
Dumping fifty .py files on PYTHONPATH is how names collide. A package is a fence: campus_gate, rsil_fees, lab_dht. Internships that skip the fence copy gst.py next to app.py until nobody knows which gst is which.
Laptop: package layout and a relative import
# rsil_fees/__init__.py
from .late import late_fee
from .gst import add_gst
# rsil_fees/late.py
def late_fee(days):
if days <= 0:
return 0
return 25
# app.py — absolute name from the project root
from rsil_fees import late_fee
print(late_fee(4))
Relative imports are for inside that folder
from . import fees means “the fees sibling in this package,” not “whatever fees is on the USB.” from .. import tools walks up one package — easy to get wrong, so we name the rule: relative imports stay inside the package tree; application scripts use the public name (import rsil_fees). Running a file inside the package as a script is a common way to break relative imports. Launch the app from the project root.
This sandbox cannot create folders. You will practise a “package-shaped” pair of functions and a public report() that the fake __init__ would have exported.
Words that matter
- Package
- A named folder of modules with a public import path.
- __init__
- The file that runs when the package is imported — keep it quiet.
- Relative import
- from . import fees — sibling inside this package.
Common mistakes
Avoid: Running a file inside the package as a script and wondering why from . import fees failed.
Do this: Launch the app from the project root; import the public package name.
Run it step by step
Each box is a real program. Press Run, change a number, Run again — the output must follow your code.
1. Step 1 — two sibling tools, one public report
late and gst live as functions. report is what __init__ would export. 25 and 118.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
2. Step 2 — the package name is data you would import
Callers know rsil_fees, not the folder path. Print the public name.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
On a full Python install — a package folder
__init__ is the package door. Relative imports (from . import fees) are for siblings, not for USB scripts.
No pip — a folder you named.
Public name rsil_fees; quiet __init__.
Real library code (not run in this browser sandbox)
# rsil_fees/__init__.py (keep this quiet)
from .late import late_fee
# rsil_fees/late.py
def late_fee(days):
if days <= 0:
return 0
return 25
Example program — A fake init that only re-exports
No print in init. The app prints.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Your turn — Public package report
report() returns a dict with late 25 for 4 days. Print so 25 appears.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Self-assessment
Check your understanding before you mark the lesson complete.
Progress is stored in a browser cookie on this device.