6 Things I Never Knew About Python Imports Until Recently

Day 42 of experimenting with video content.
Summary
The provided content discusses six lesser-known aspects of Python import mechanisms, including the use of __import__
, __all__
, absolute and relative imports, the sys.path
list, and the if __name__ == '__main__'
conditional for controlling script execution.
Abstract
The article "6 Things I Never Knew About Python Imports Until Recently" delves into advanced Python import features that may not be widely known among developers. It covers the direct use of the __import__
function for dynamic module loading, the __all__
variable for specifying which functions or classes are available for import *
, and the differences between absolute and relative imports, which are crucial for organizing code in large projects. The author also explains how sys.path
determines where Python looks for modules and how to manipulate it for custom import paths. Additionally, the article highlights the importance of the if __name__ == '__main__'
conditional to ensure code execution only when a script is run directly, not when it is imported as a module. These insights aim to enhance the reader's understanding of Python's import system and improve their coding practices.
Opinions
__import__
is presented as a powerful feature for dynamic module loading, suggesting flexibility in how modules are handled in Python.__all__
mechanism is recommended for controlling the exported objects from a module, thus promoting better encapsulation and cleaner interfaces.sys.path
is suggested as a practical solution for importing modules from non-standard locations, which can be particularly useful in custom development environments.if __name__ == '__main__'
conditional is an essential tool for preventing unintended code execution when modules are imported, thereby enhancing code organization and maintainability.Day 42 of experimenting with video content.
Our normal way of importing stuff eg. pandas
import pandas as pd
df = pd.DataFrame()
Using __import__
pd = __import__('pandas')
df = pd.DataFrame()
Let’s say we have 2 files a.py
and b.py
# a.py
from b import *
# b.py
def test1():
pass
def test2():
pass
def test3():
pass
Currently, a.py
will import everything from b.py
due to the from b import *
statement. However, this might change if we add __all__
to b.py
# a.py
from b import *
# b.py
def test1():
pass
def test2():
pass
def test3():
pass
__all__ = ['test1', 'test2']
Here, the __all__
list defines what will be imported from b.py
when the statement from b import *
is used. In this case, only test1
and test2
will be imported from b.py
, and test3
will not be.
Let’s say we have a hello.py
nested deep within a bunch of folders:
test1
|-test2
|-test3
hello.py
a.py
Contents of hello.py
:
def hello():
print('hello')
Now, let’s say we are using a.py
and we wish to import the hello
function from hello.py
. To do this, we can use absolute imports.
# a.py
from test1.test2.test3.hello import hello
hello()
# hello
Let’s say we have 2 files in the same folder, a.py
and b.py
# a.py
from b import *
if __name__ == '__main__':
print('only runs when i run a.py directly')
# b.py
def hello_from_b():
print('hello from b.py')
if __name__ == '__main__':
print('only runs when i run b.py directly')
When I run a.py
directly, I get only runs when i run a.py directly
only. Whatever is inside if __name__ == '__main__'
of b.py
does not run UNLESS I explicitly run b.py
itself.
This is useful to prevent ourselves from accidentally running code that we don’t want to run.
When we run a Python script directly eg a.py
, __name__
in a.py
will be '__main__'
. But all other __name__
in other files will be equal to their Python script name eg. b.py
's __name__
will be b
. Which is why the if statement if __name__ == '__main__'
works.
import sys
print(sys.path)
# ['/Users/zlliu/repos/main',
# '/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip'
# ...
# ]
# list of absolute paths Python will search to import stuff from
Here, when we print sys.path
, we will get a list of absolute paths (as strings in a list). These paths are the paths that Python will search for when attempting to import stuff.
Which means that we can actually manually add our own paths into sys.path
if we want Python to import stuff from some weird folder in our computer.
Let’s say we have some modules in our directory /apple/orange/pear
which we want to import from.
import sys
sys.path.append('/apple/orange/pear')
Now, since /apple/orange/pear
is in sys.path
, Python will search this directory when importing stuff, and we will be able to import stuff from this directory.
Let’s say we have 3 files
test
|- b.py
|- c.py
a.py
a.py
imports from b.py
b.py
imports from c.py
# c.py
def hello_from_c():
print('hello')
# b.py
from .c import hello_from_c
# a.py
from test.b import hello_from_c
hello_from_c()
# hello
Here, the statement from .c import hello_from_c
is a relative import. The .
in front means that c
is in the SAME directory.
This can be useful if our absolute paths are pretty long and we don’t wish to type them all out.
Hope this was clear and easy to understand.
If this story was helpful and you wish to show a little support, you could:
These actions really really help me out, and are much appreciated!
Ebooks I’ve Written: https://zlliu.co/ebooks
LinkedIn: https://www.linkedin.com/in/zlliu/
5 Reasons Why Python is Losing Its Crown
Four advanced tricks to give your data science and machine learning classes the edge you never knew they needed
Some common pitfalls in feature selection and feature engineering, and how to get around them
Improve Python Code Quality with Clean Coding Practices!