Python modules are files containing Python code, including definitions for functions, classes, and variables. When you import a module, all the code in that module is executed and the definitions are loaded into memory. This allows you to reuse code across multiple files and access definitions easily.
However, sometimes you may only need certain functions or classes from a module rather than everything. Importing specific elements has advantages like cleaner namespaces, better readability, and faster load times. Luckily, Python provides easy ways to import only what you need.
Key concepts are accompanied by annotated code examples for clarity. You will gain a deep understanding of how to properly leverage Python’s flexible import system to create clean, modular code. Let’s get started!
Table of Contents
Open Table of Contents
Python Module and Import Basics
Before diving into selective imports, let’s recap some Python import fundamentals:
What is a Module?
A Python module is simply a Python script file containing function, class, variable definitions and other executable code. By convention, module filenames end in .py
.
Modules allow code reuse by letting you import definitions from one file into another. The import
statement is used to load a module.
# Import the math module
import math
The PYTHONPATH
Python searches a list of directories called the PYTHONPATH to locate modules. This includes the current directory and standard library directories. You can view/modify the PYTHONPATH through sys.path
.
Importing Modules
The basic import
statement loads the target module and all its definitions. An alias can optionally be used to reference the module with a different name.
# Import module 'math'
import math
# Import module as 'm'
import math as m
From Imports
The from
form allows importing specific definitions from a module directly into the current namespace.
# Import the sqrt function from math
from math import sqrt
# Reference sqrt directly
print(sqrt(25))
This recap covers the key concepts needed to understand selective imports. Now let’s explore the techniques for importing only what you need.
Techniques for Selective Imports in Python
Python provides several ways to import specific functions, classes, variables, or submodules rather than everything:
1. Basic Import
Import the module normally, then access the desired definitions with dot notation.
# Import the full math module
import math
# Access pi constant directly from math
print(math.pi)
- Pros: Simple, explicit. Makes it clear where names come from.
- Cons: Can clutter local namespace with unused definitions.
2. From Import
Use from <module> import
to import names directly into current namespace.
# Import sqrt function from math module
from math import sqrt
# Use sqrt directly
print(sqrt(10))
- Pros: Convenient access to imported definitions. Avoids module.name prefix.
- Cons: Pollutes namespace, unclear where names come from.
3. Import as
Import module as an alias, then access attributes through the alias.
# Import math module as 'm'
import math as m
# Access pi through the m alias
print(m.pi)
- Pros: Lets you pick a short, convenient alias.
- Cons: Still loads entire module.
4. From … Import as
Import specific names as aliases with from <module> import <name> as <alias>
# Import sqrt as s
from math import sqrt as s
# Use alias s instead of sqrt
print(s(4))
- Pros: Combines the best of aliasing and selective name imports.
- Cons: The meaning of abbreviated names may not be apparent.
5. Relative Imports
If you need to import definitions from within the same top-level package, use relative imports like:
from . import module2
from .module2 import func
from ..package import module3
- Pros: Allows cleaner imports within packages.
- Cons: Can make code less portable.
6. Import Library Objects
Import specific library objects rather than the entire library module:
# Import urljoin function from urllib.parse
from urllib.parse import urljoin
# Import Pi constant from math
from math import pi
- Pros: Most granular, least likely to cause namespace issues.
- Cons: Not always clear which module names come from.
Now that you’ve seen techniques for selective importing, let’s go over when you should use each approach.
When to Use Each Selective Import Technique
Choosing the right selective import syntax involves tradeoffs between convenience, readability, and namespace hygiene. Here are some guidelines on when to use each form:
-
Import module: Good for importing larger modules you use often. Provides context.
-
From import: Good for importing a few names from a large library. More convenient than using module.name.
-
Import as: Best when you need to import a large module using a short name.
-
From…import as: Use when you want to import a few names from a module with different local aliases. Can make long names more readable.
-
Relative imports: Help avoid ambiguity when importing between modules in the same package. Use these over absolute paths within a package.
-
Import library objects: For importing individual functions, constants, classes rather than entire libraries. Least likely to cause naming collisions.
Some key principles:
-
Favor explicitness over convenience when importing many names from a module.
-
Use
import module
and module.name when importing a large module wholesale. -
Prefer
from module import name
overfrom module import *
to be more explicit. -
Use relative imports within packages rather than absolute module paths.
Best Practices for Organizing Module Imports
Follow these module import best practices to create clean, maintainable Python code:
-
Group imports: Organize imports into sections separating built-in, third-party and custom modules.
-
Order alphabetically: Sort imports alphabetically within each import group for consistency and readability.
-
Put all imports at top: Import everything at the beginning of a module before any code and functions to act as documentation for dependencies.
-
Limit line length: Stick to a max line length of 79 characters for imports to avoid messy wrapping. Use parentheses for line continuations.
-
Avoid relative imports: Use absolute imports like
import package.module
instead of relative ones likefrom ..module import name
when possible for cleaner structure between files. -
Use aliases wisely: Aliases can help shorten long module names, but use them sparingly and make sure their meaning is clear.
-
Use linters: Tools like
pylint
andflake8
help check your imports and can auto-organize them. Leverage linters to reinforce best practices.
Properly structuring imports makes large projects easier to navigate and understand for developers. Stick to these guidelines in your own code.
Handling Name Collisions When Selectively Importing
Name collisions can occur when selectively importing functions or classes of the same name from different modules. For example:
# myprogram.py
from math import sqrt
from cmath import sqrt
This is ambiguous - which sqrt()
will be used?
Here are some ways to handle namespace collisions:
- Import modules with different aliases:
import math as m
import cmath as c
Then use m.sqrt()
or c.sqrt()
to disambiguate.
- Rename on import:
from math import sqrt as m_sqrt
from cmath import sqrt as c_sqrt
- Import objects directly:
from math import sqrt
from cmath import phase
Since sqrt
and phase
are different names, no collision.
- Fully qualify name references:
import math
import cmath
print(math.sqrt()) # Unambiguous
- Rename references in code:
import math
import cmath
m_sqrt = math.sqrt # Rename
print(m_sqrt())
Carefully handling name collisions ensures that the right definitions are being accessed reliably throughout your code.
Advanced Importing with importlib
Python’s importlib
module provides lower-level import functions for advanced scenarios:
import importlib
# Import module dynamically
math = importlib.import_module('math')
# Reload module
importlib.reload(math)
# Import specific object
sqrt = importlib.import_module('math.sqrt')
Key capabilities:
-
Dynamic imports: Import modules by name as strings using
import_module()
-
Granular imports: Import submodules or specific objects within a module like
math.sqrt
-
Module reloading: Reload a module after code changes using
reload()
rather than re-importing -
Abstract resources: Import from zip files, network resources, or other non-file resources using loader objects
-
Advanced metadata: Introspect modules using the
ModuleSpec
andModuleFinder
APIs
The importlib
module is useful for cases like plugins or dynamic module loading where flexibility is needed.
Conclusion
This guide covered several techniques for selectively importing functions, classes, and objects from Python modules:
- Basic module import and attribute access
from module import name
syntax- Alias imports like
import module as name
- Relative imports within packages
- Direct import of specific library objects
- Using
importlib
for advanced import tasks
Key takeaways:
- Favor explicitness over convenience when importing many module contents.
- Use aliases to shorten long module names sparingly.
- Organize imports alphabetically in groups by type for readability.
- Handle name collisions through aliases, renaming, or fully qualified names.
Selective importing helps organize your namespaces by loading only necessary definitions. Use these techniques to write clean, modular Python code optimized for maintainability and performance.