Python Module 6 – Modules, packages and the standard library
Packages, __init__.py and relative imports
Organise Python modules into packages with __init__.py, write absolute and relative imports, run package code with python -m, and import the right name.
What you will learn
- Organise modules into a package and predict which of its files an import runs
- Resolve a relative import to the absolute module name it refers to
- Run a module of a package with python -m from the right folder
- Recognise a namespace package and the mistakes it can hide
- Distinguish the name you install from the name you import
Before you start
What you’ll learn · Before you start
What you will learn
- Organise modules into a package and predict which of its files an import runs
- Resolve a relative import to the absolute module name it refers to
- Run a module of a package with python -m from the right folder
- Recognise a namespace package and the mistakes it can hide
- Distinguish the name you install from the name you import
Before you start
On this page
Three modules about class marks, marks.py, students.py and reports.py, belong together, and a second project
of yours may well have a reports.py of its own. A package: A folder of modules that is imported as one unit, such as school/ with school.marks and school.reports. A regular package has an __init__.py, which runs when anything of the package is first imported. puts them in one folder,
school/, under one name: they become the modules school.marks, school.students and school.reports, and related
code lives together instead of crowding the top level.
A regular package also has a file called __init__.py, which runs when the package is first imported and decides what
import school gives you. Modules inside a package refer to each other with
absolute import: An import that spells out a module's full dotted name from the top level, such as from school.marks import grade. It means the same thing in every file., which spell out the full name (from school.marks import grade),
or relative import: An import that starts with dots, such as from .marks import grade. One dot is the package of the module that holds the import, and each extra dot goes up one package. Only the from form can be relative., which start from the module’s own package
(from .marks import grade). Code that uses relative imports has to run as part of its package, and
python -m school.reports is how you run it that way.
Importing a submodule loads its package first
This is the project of this lesson. main.py sits next to the school folder, and every file of the package has a
module name made of the folder and the file:
The files of the school package and their module names
Text description of the diagram
The diagram shows the folder school_app, where you run Python, and inside it two things.
- main.py, which runs as the module __main__ when you start it, and imports the package with import school.
- The folder school, which is the package school. Its files are: __init__.py, which is the package school itself; __main__.py, which python -m school runs; reports.py, the module school.reports; marks.py, the module school.marks; and students.py, the module school.students.
- Arrows show the imports that import school runs, each labelled with the module it names: __init__.py imports from .marks and from .reports, and reports.py imports from .marks and from .students. The single dot means "this package", so .marks is school.marks.
main.py uses the package three ways: through the package itself, through a name the package re-exports, and
through a submodule. The other tabs show the files of the package:
Python · school_app/main.py
import school
from school import report_card
from school.marks import grade
print(report_card("Ravi"))
print("Grade for 74.9:", grade(74.9))
print("Names:", school.__name__, "and", school.marks.__name__)
print("Public API:", school.__all__) Output
Ravi: average 71.7, grade C Grade for 74.9: C Names: school and school.marks Public API: ['average', 'grade', 'report_card']
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 main.py
school/__init__.py · school_app/school/__init__.py
"""A small package for class marks: averages, grades and report cards."""
from .marks import average, grade
from .reports import report_card
__all__ = ["average", "grade", "report_card"] school/marks.py · school_app/school/marks.py
"""Averages and letter grades."""
GRADE_BANDS = [(90, "A"), (75, "B"), (60, "C"), (40, "D")]
def average(marks):
return round(sum(marks) / len(marks), 1)
def grade(score):
for lowest, letter in GRADE_BANDS:
if score >= lowest:
return letter
return "E" school/students.py · school_app/school/students.py
"""The class list (a real program would read it from a file)."""
STUDENTS = {
"Asha": [92, 88, 95],
"Ravi": [71, 64, 80],
"Meera": [55, 62, 49],
} school/reports.py · school_app/school/reports.py
"""Report cards, built from the other modules of the package."""
from .marks import average, grade
from .students import STUDENTS
def report_card(name):
score = average(STUDENTS[name])
return f"{name}: average {score}, grade {grade(score)}"
if __name__ == "__main__":
print(report_card("Asha")) school/__main__.py · school_app/school/__main__.py
"""What python -m school runs: a report card for every student."""
from .reports import report_card
from .students import STUDENTS
for name in sorted(STUDENTS):
print(report_card(name)) Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
- Dotted names. A module inside a package is named after its path:
school/marks.pyisschool.marks, and a subpackageschool/reports/with acards.pyin it would giveschool.reports.cards. Each part of the name except the last must be a package. - The package is a module too.
import schoolcreates a module object for the folder, whose code is__init__.py. Importing a submodule imports its packages first, soimport school.marksrunsschool/__init__.pybeforemarks.py, and bindsmarksas an attribute ofschool. __init__.pysets the front door. This one importsreport_card,averageandgradefrom the submodules, so callers can writefrom school import report_cardwithout knowing which file defines it. Its__all__lists the public names;from school import *imports exactly those, and readers and tools treat the list as the package’s interface.
Which files ran for those three lines, and in what order? Step through them file by file:
The drawing shows the whole scene; its 7 steps are listed below.
Every step as text
- import school. Line 1 of main.py, import school, finds the folder school/ on sys.path. It holds an __init__.py, so school is a regular package, and Python loads the package first: a module named school whose code is __init__.py.
- The first line of __init__.py. __init__.py starts with from .marks import average, grade. The dot means this package, so Python loads school.marks: marks.py runs to its end.
- The second line. from .reports import report_card loads school.reports. reports.py starts running, and its own first line asks for .marks once more.
- Cached, then one more. school.marks is already in sys.modules, so reports.py gets average and grade without running marks.py again. Its next line loads school.students, and then reports.py finishes.
- The front door is ready. Back in __init__.py, average, grade and report_card are now names of the package, and __all__ lists them. Each submodule that was loaded is an attribute of the package too, such as school.marks.
- Names for main.py. import school binds the name school in main.py. Line 2, from school import report_card, finds the package in sys.modules and takes the name that __init__.py re-exported.
- Nothing new to load. Line 3, from school.marks import grade, finds school.marks in sys.modules as well. Four files ran, once each, in the order that load_order.py prints: school, school.marks, school.reports and school.students.
The order is not a guess. Python raises an A signal that Python sends at certain points while it runs, such as each time it loads a module. A function registered with sys.addaudithook() receives every one, with the event's name and its details.
called import each time it loads a module, and this program collects those events while it imports the package:
"""Which files of the package run, and in what order, when a program imports school."""
import sys
loaded = []
def watch(event, args):
# Python raises the audit event "import" each time it loads a module.
if event == "import" and args[0].startswith("school"):
loaded.append(args[0])
sys.addaudithook(watch)
import school
print("import school loaded:", ", ".join(loaded))
loaded.clear()
from school import report_card
from school.marks import grade
print("the next two imports loaded:", ", ".join(loaded) or "nothing")
print("school.marks is an attribute of school:", hasattr(school, "marks")) Output
import school loaded: school, school.marks, school.reports, school.students the next two imports loaded: nothing school.marks is an attribute of school: True
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 load_order.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
The four files loaded in the order of the figure, and the next two imports loaded nothing new. Press Edit, change
import school to import school.students and run it again: the package still loads first, and its __init__.py
still brings in the other three modules.
An empty __init__.py is fine and common. Whatever you put in it runs on the first import of anything in the
package, so keep it to re-exports: a slow import or a file read in __init__.py slows down every program that
touches one small submodule, and __init__.py files that import half the package are a frequent source of circular
imports.
Key idea
Any import from a package runs its __init__.py first, once per program, so every program that uses one small
module of the package also pays for whatever __init__.py imports.
Checkpoint
Check: What importing a package runs
A relative import starts from the module’s own package
Inside school/reports.py, these pairs mean the same thing:
| Relative import | Absolute import | Refers to |
|---|---|---|
from .marks import grade |
from school.marks import grade |
school/marks.py |
from . import students |
from school import students |
school/students.py |
from .. import config (in school/reports/cards.py) |
from school import config |
school/config.py |
- One dot means the package that holds the current module; each extra dot goes up one package. In an
__init__.py, the module is the package itself, so one dot means that package. - Only the
fromform can be relative:import .marksis a syntax error, because.markscould not be used as a name afterwards. - Relative imports follow the package, not the folder. Python works them out from the importing module’s
package name, which it keeps in
__package__. Going above the top-level package fails with “attempted relative import beyond top-level package”.
Before it searches for anything, Python turns a relative import into an absolute module name. Step through that
conversion for from ..marks import grade inside school/reports/cards.py, the step the exercise of this lesson asks
you to write:
The drawing shows the whole scene; its 7 steps are listed below.
Every step as text
- Two dots. from ..marks import grade starts with dots, so it is relative. Before it searches for anything, Python turns it into an absolute module name, using the name of the module that contains the import.
- Whose import is it?. The import is in school/reports/cards.py, the module school.reports.cards. Python keeps the package that module belongs to, school.reports, in its __package__.
- One dot is the package. The first dot means that package, school.reports. In an __init__.py the module is the package itself, so there one dot means the package whose file it is.
- Each extra dot goes up. The second dot goes up one package, from school.reports to school. A third dot would have to go above school, and there is nothing above a top-level package.
- The rest is added. What follows the dots, marks, is added to the end: school.marks. From here on the import is an ordinary absolute one, exactly as if it said from school.marks import grade.
- An ordinary import. Python imports school.marks through sys.modules and the folders of the package, and binds grade in cards.py. The dots were only a way of writing the full name.
- The two errors. Too many dots fail with "attempted relative import beyond top-level package". A file run by its path is __main__, with no package to start from, and fails with "attempted relative import with no known parent package".
Which should you write? Absolute imports are unambiguous and are what the official style guide, PEP 8, recommends by default. Relative imports are shorter inside a deep package and keep working if the whole package is renamed or moved inside another one. Many projects use absolute imports everywhere and relative ones only between modules of the same package; whichever you choose, use it consistently.
Checkpoint
Check: Relative and absolute imports
Run a module of a package by its name, not its path
reports.py has a small demo under its __name__ guard. Here are three ways of running files of the package,
started from the school_app folder, with what each one printed:
"""Run files of the package three ways, as you would type them in a terminal."""
import subprocess
import sys
def run(typed, *args):
print("$", typed)
result = subprocess.run([sys.executable, *args], capture_output=True, text=True)
if result.stderr:
# The last line of a traceback, or a warning, says what went wrong.
print(result.stderr.strip().splitlines()[-1])
print(result.stdout, end="")
run("python school/reports.py", "school/reports.py")
run("python -m school.reports", "-m", "school.reports")
run("python -m school", "-m", "school") Output
$ python school/reports.py ImportError: attempted relative import with no known parent package $ python -m school.reports <frozen runpy>:130: RuntimeWarning: 'school.reports' found in sys.modules after import of package 'school', but prior to execution of 'school.reports'; this may result in unpredictable behaviour Asha: average 91.7, grade A $ python -m school Asha: average 91.7, grade A Meera: average 55.3, grade D Ravi: average 71.7, grade C
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 commands.py
The second command printed a warning before the report card. Step through what -m did, and watch reports.py run
twice under two names:
The drawing shows the whole scene; its 6 steps are listed below.
Every step as text
- A module by name. You type python -m school.reports in school_app/. -m puts the current folder first on sys.path and finds the module by its dotted name, which means importing the package school first.
- The package loads. Importing the package runs school/__init__.py. Its second line, from .reports import report_card, needs school.reports.
- reports.py, the first time. school/reports.py runs under its real name, school.reports. Its __name__ is 'school.reports', so the guarded demo does not run, and __init__.py gets report_card.
- The warning. Back in runpy, the module it was asked to run is already in sys.modules. That is the RuntimeWarning in the output: the file is about to run a second time, which may lead to unpredictable behaviour.
- reports.py, the second time. runpy runs reports.py again, this time as __main__ with __package__ set to "school", so its relative imports resolve. The guard is true now, and the demo prints Asha: average 91.7, grade A.
- Two copies of one file. The file now backs two modules, school.reports and __main__, each with its own top-level variables. Keep entry points out of what __init__.py imports, or put them in __main__.py.
python school/reports.pyfails. Run by its path, the file becomes the top-level module__main__, which belongs to no package, so its first relative import has nothing to start from. Python also putsschool/itself at the front ofsys.path, so even an absolutefrom school.marks import gradewould not find the package.python -m school.reportsworks.-msearchessys.pathfor the module by name, imports its packages first (runningschool/__init__.py) and then runs the file as__main__with__package__set to"school", so the dots resolve. With-m, the first entry ofsys.pathis the current folder, so run it from the folder that containsschool/.- The warning is worth reading.
__init__.pyhad already importedschool.reportsto re-exportreport_card, so Python ran that file twice: once asschool.reportsand once as__main__. Two copies of a module also mean two copies of its top-level variables, which leads to confusing bugs in bigger programs. Keep entry points out of what__init__.pyimports, or put them in__main__.py. python -m schoolrunsschool/__main__.py. That file is the package’s command-line entry point. The documentation recommends keeping it short and without a__name__guard: it imports what it needs and runs.
The browser runner cannot type a command, but the runpy module, which -m uses, does the same thing from Python:
"""What python -m school does, from inside Python: runpy runs the package's __main__.py."""
import runpy
# run_module() returns the globals of the code it ran, which this program does not need.
names = runpy.run_module("school", run_name="__main__") Output
Asha: average 91.7, grade A Meera: average 55.3, grade D Ravi: average 71.7, grade C
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 run_main.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
Checkpoint
Check: Running a module with python -m
A folder without an init file imports as a namespace package
A folder without __init__.py can still be imported. It becomes a
namespace package: A package without an __init__.py (PEP 420). It has no code of its own and no __file__, and its parts may come from several folders on sys.path. Python makes one only when no module or regular package of that name exists. (PEP 420): a package with no code of its own and no __file__,
whose parts may even come from several folders on sys.path. Large projects use them to ship separate distributions
under one name, such as plugins that install into a shared namespace.
Python · namespace/main.py
import json
import plugins.summary
with open("json/marks.json", encoding="utf-8") as file:
marks = json.load(file) # the standard library's json: the folder has no __init__.py
print(plugins.summary.describe(marks))
print("plugins.__file__ is", plugins.__file__)
print("plugins.__path__ is a", type(plugins.__path__).__name__) Output
3 students; top mark 92 (Asha) plugins.__file__ is None plugins.__path__ is a _NamespacePath
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 main.py
plugins/summary.py · namespace/plugins/summary.py
def describe(marks):
best = max(marks, key=marks.get)
return f"{len(marks)} students; top mark {marks[best]} ({best})" json/marks.json · namespace/json/marks.json
{"Asha": 92, "Ravi": 71, "Meera": 55} Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
This folder holds two folders without __init__.py, and they end up very differently. Step through the search that
each import makes:
The drawing shows the whole scene; its 7 steps are listed below.
Every step as text
- import json. main.py starts with import json. Python searches sys.path in order, and the first folder, the script's own, holds a folder called json.
- Noted, not taken. That folder has no __init__.py, so it is not a regular package. Python notes it as a possible part of a namespace package and keeps searching the rest of sys.path.
- The real json wins. In the standard library it finds json/ with an __init__.py, a regular package. A regular package ends the search at once, so json is the standard module and json.load() reads marks.json.
- import plugins. import plugins.summary imports plugins first. The script folder holds plugins/ without an __init__.py, so it is noted, and the search goes on.
- Nothing else. No other folder of sys.path has a module, a regular package or even a folder called plugins. The noted folder is all there is.
- A namespace package. At the end of the search the noted folders become one namespace package. plugins has no code of its own, so its __file__ is None, and its __path__ is a _NamespacePath, as the output shows.
- A module inside. summary.py in that folder is an ordinary module, plugins.summary. Its describe() prints the first line of the output: 3 students; top mark 92 (Asha).
plugins imported without an __init__.py; its __file__ is None and its __path__ is a special sequence of
folders that Python searches again when the folders on sys.path change. The json folder shows the other side of
the rule: a folder without __init__.py never hides a real module or package. Python remembers such a folder as a
possible namespace package and keeps searching, and the standard library’s json module, found later, wins. That
differs from a file called json.py, which would hide it, as the previous lesson showed.
The convenience has a cost. Any folder on sys.path can be imported, so an import that meets a stray folder of the
same name, such as a folder of data files or one left over after a rename, gives you an empty package instead of a
clear ModuleNotFoundError, and the mistake only shows up later as an AttributeError. Give your own packages an
__init__.py, even an empty one, and keep namespace packages for the plugin case.
Checkpoint
Check: Namespace packages
The name you install is not always the name you import
Packages on PyPI are distribution package: A project as pip installs it, under its name on PyPI, such as pillow. It holds one or more import packages, whose names may differ from it: pillow is imported as PIL.: the name you give to
pip install. What your code imports is an import package, and nothing forces the two names to match:
| You install | You import | Why |
|---|---|---|
pip install requests |
import requests |
most projects keep the two names equal |
pip install pillow |
from PIL import Image |
Pillow began as a fork of an older library called PIL and kept its import name |
The packaging guide calls matching names only a convention: the package index does not enforce any link between the two, and one distribution can even provide several import packages. So when you see an import you do not recognise, look it up in the project’s documentation before installing a package of that name: a package with the matching name may be a different project, or one made to catch exactly that guess.
Checkpoint
Check: The name you install and the name you import
Practise: work out a relative import
Before it searches for anything, Python turns every relative import into an absolute module name, using the name of the module that contains it. Write that step yourself, with both of its error messages, and the dots of a relative import stop being guesswork.
Exercise · Medium · Python
Work out what a relative import refers to
Write absolute_name(module, dots, name="", is_package=False), which returns the absolute module name that a relative import refers to, the way Python works it out:
moduleis the full name of the module that contains the import, such as"school.reports".dotsis the number of leading dots (1 or more) andnameis what follows them, sofrom ..marks import gradeinsideschool.reports.cardsisabsolute_name("school.reports.cards", 2, "marks"), which gives"school.marks". Forfrom . import marks,nameis"".- One dot means the package that holds the module; each extra dot goes up one more package. In
school.reports, that package isschool. When the module is itself a package (its code is an__init__.py),is_packageisTrueand one dot means that package:absolute_name("school", 1, "marks", is_package=True)is"school.marks". - A module with no package around it (
"main", or"__main__"when a file is run as a script) raisesImportError("attempted relative import with no known parent package"). - Going up past the top-level package raises
ImportError("attempted relative import beyond top-level package").
The sample tests import your function from relative.py.
Starter code · relative.py
def absolute_name(module, dots, name="", is_package=False):
"""The absolute module name that `from <dots><name> import ...` inside `module` refers to."""
# Replace this line with your code.
return name The sample tests · test_relative.py
from relative import absolute_name
def error_message(*args, **kwargs):
"""The message of the ImportError that absolute_name raises (None if it raises nothing)."""
try:
absolute_name(*args, **kwargs)
except ImportError as error:
return str(error)
return None
def test_one_dot():
"""one dot is the package that holds the module"""
assert absolute_name("school.reports", 1, "marks") == "school.marks"
assert absolute_name("school.reports.cards", 1, "layout") == "school.reports.layout"
def test_dot_alone():
"""from . import x refers to the package itself"""
assert absolute_name("school.reports", 1) == "school"
assert absolute_name("school.reports.cards", 2) == "school"
def test_two_dots():
"""each extra dot goes up one package"""
assert absolute_name("school.reports.cards", 2, "marks") == "school.marks"
assert absolute_name("app.ui.forms.fields", 3, "config.paths") == "app.config.paths"
def test_package_init():
"""in an __init__.py, one dot is the package itself"""
assert absolute_name("school", 1, "marks", is_package=True) == "school.marks"
assert absolute_name("school.reports", 1, "cards", is_package=True) == "school.reports.cards"
assert absolute_name("school.reports", 2, "marks", is_package=True) == "school.marks"
def test_no_parent_package():
"""a module outside any package cannot use a relative import"""
assert error_message("main", 1, "utils") == "attempted relative import with no known parent package"
assert error_message("__main__", 1) == "attempted relative import with no known parent package"
def test_beyond_top_level():
"""going above the top-level package is an error"""
assert error_message("school.reports", 2, "marks") == "attempted relative import beyond top-level package"
assert error_message("school", 2, "x", is_package=True) == "attempted relative import beyond top-level package"
assert error_message("school.reports", 1, "marks") is None A hint
Start from the package: module.split(".") gives the parts, and the package is all of them except the last one, or all of them when is_package is True. An empty package means "no known parent package". Then each dot after the first removes one more part from the end; if you need to remove more parts than there are, the import goes beyond the top-level package. Join what is left, and add name when it is not empty.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Fourteen questions follow on the five ideas of this lesson. They come one at a time, starting from the idea where your answers so far are weakest, and each one shows its reasoning as soon as you check it:
Practice that adapts to you
Practise this lesson
14 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Fresher · Why does from . import utils fail when you run the file directly, and how do you run it instead?
A relative import is resolved against the package of the module that contains it, which Python keeps in
__package__. When you run a file by its path, as in python app/cli.py, Python runs it as the top-level module
__main__, which belongs to no package, so the dot has nothing to start from and the import fails with “attempted
relative import with no known parent package”. Run it as a module of its package instead: from the folder that
contains app/, type python -m app.cli. Python then imports app first, running its __init__.py, and runs
cli.py with __package__ set to "app", so .utils means app.utils. Rewriting the import as
from app import utils does not rescue the direct run, because the folder that contains app/ is still not on
sys.path.
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Mid to senior
Importing one small module of your team's package, mypkg.textutils, takes 1.8 seconds. mypkg/__init__.py imports every submodule so that users can write from mypkg import Report. How do you confirm where the time goes, and how do you make the import fast without breaking that line?
-
Mid to senior
A nightly job is started with python -m shop.orders. Its log shows the start-up line twice, a RuntimeWarning mentions sys.modules, and a counter in shop/orders.py differs between the job and the modules that import it. Explain what is happening and how you would restructure the entry point.
Key takeaways
- A package is a folder of modules with an
__init__.py; its modules get dotted names such asschool.marks, and importing one runs the package’s__init__.pyfirst. - Keep
__init__.pylight, because every import from the package runs it: re-export the public names and list them in__all__. - Relative imports (
from .marks import grade) work only in thefromform and only inside a package; one dot is the current package and each extra dot goes up one. - Run code that lives in a package with
python -m package.modulefrom the folder above the package, andpython -m packageruns its__main__.py. - A folder without
__init__.pyis a namespace package: it never hides a real module, but it imports even when empty. - The PyPI name and the import name can differ (
pillowandPIL), so check the project’s documentation before you install a guess.
Terms in this lesson
- absolute import
- An import that spells out a module's full dotted name from the top level, such as from school.marks import grade. It means the same thing in every file.
- distribution package
- A project as pip installs it, under its name on PyPI, such as pillow. It holds one or more import packages, whose names may differ from it: pillow is imported as PIL.
- namespace package
- A package without an __init__.py (PEP 420). It has no code of its own and no __file__, and its parts may come from several folders on sys.path. Python makes one only when no module or regular package of that name exists.
- package
- A folder of modules that is imported as one unit, such as school/ with school.marks and school.reports. A regular package has an __init__.py, which runs when anything of the package is first imported.
- relative import
- An import that starts with dots, such as from .marks import grade. One dot is the package of the module that holds the import, and each extra dot goes up one package. Only the from form can be relative.
References
- The Python Tutorial: Packages (Python Software Foundation)
- The import system: Packages (Python Software Foundation)
- The import system: Submodules (Python Software Foundation)
- The import statement: the audit event import (Python Software Foundation)
- sys.addaudithook (The Python Standard Library) (Python Software Foundation)
- __main__.py in Python packages (Python Software Foundation)
- runpy, locating and executing Python modules (Python Software Foundation)
- Command line and environment: the -m option (Python Software Foundation)
- PEP 8: Style Guide for Python Code (Imports) (Python Software Foundation)
- PEP 328: Imports, multi-line and absolute/relative (Python Software Foundation)
- PEP 420: Implicit namespace packages (Python Software Foundation)
- Distribution package vs. import package (Python Packaging Authority)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress