Python modules have 2 syntaxes for importing.
import x
from x import y
Absolute imports are used for importing top-level modules and only top level modules. These are ones that are globally installed, either inside of Python core or via a package manager (e.g. pip
).
import json # Python core
import yaml # Installed via `pip install pyyaml`
When you declare a global import, Python looks for the __init__.py
of a top-level module. When you are working inside of a virtual environment, this is
~/.virtualenvs/<your_virtualenv>/lib/python2.7/site-packages/<package_name>/__init__.py
If this file is populated, it will return all variables declared at the top scope.
# hello/__init__.py
# This file returns `a` and `c` when imported
a = 'b'
def c():
d = 'e'
THIS SECTION SHOULD BE AVOIDED IF YOU ARE TRYING TO DEVELOP CROSS-VERSION MODULES
Inside Python 2, import x
can resolve local files as modules. There are 2 cases:
If a folder is named the same as the top level module, an __init__.py
is looked for. If that exists, then we will follow the same variable procedure as an absolute module (if empty, collect from sibling files. otherwise, return exposed variables.)
hello/
hello.py # `import world`
world/
__init__.py # first looks for this
# If not found, looks here
~/.virtualenvs/<your_virtualenv>/lib/python2.7/site-packages/world/__init__.py
If a file is named the same as the top level module, the local file's contents will be returned.
hello/
hello.py # `import world`
world.py # first looks for this
# If not found, looks here
~/.virtualenvs/<your_virtualenv>/lib/python2.7/site-packages/world/__init__.py
The order that these cases are dealt with is folder
-> file
-> top-level
hello/
hello.py # `import world`
world/
__init__.py # first looks for this
world.py # second looks here
# If not found, looks here
~/.virtualenvs/<your_virtualenv>/lib/python2.7/site-packages/world/__init__.py
Requests for absolute modules are returned the exact same between from x import y
and import x
. The difference is that the items returned as only those in the import y
piece.
# hello/__init__.py
# `from hello import a` will return `a` as a variable
a = 'b'
def c():
d = 'e'
In addition to this, Python 2.5+ and 3 support relative imports.
# Inside of hello/hello.py
from .world import status
When resolving a relative module, Python first looks for a folder with that name and its __init__.py
. If that exists, it will extract the variable from the __init__.py
as in import x
. If it does not exist, it will look for world.py
at the same level as the import. If that is not found, an Exception
will be raised.
hello/
hello.py # Resolving .world from hello/hello.py
world/
__init__.py # Looks for file here
world.py # Looks here second
# If not found, raise an exception
Once resolved, the requested variables inside of the module are returned. If these don't exist an exception will be raised.
# hello/world.py
status = 'Operational'
time = 'Now'
# Inside of hello/hello.py
from .world import status # 'Operational'
This is something that kept on catching me off-guard.
YOU CANNOT IMPORT A RELATIVE MODULE IN ITS ENTIRETY IN PYTHON 3.
YOU CAN ONLY IMPORT EXPLICIT VARIBLES!
import world # world.a, world.c are accessible
# No way to do this in Python 3.
# Must be explicit:
from .world import status, time