Importing modules is a fundamental concept in Python programming that allows you to access code from other files and packages. Modules encapsulate related code into reusable and organized units that can be shared across different scripts and programs. The import
statement is used to bring modules into the current namespace so their attributes, classes, functions and other objects can be utilized.
In this comprehensive guide, we will cover everything you need to know about importing modules in Python, including:
Table of Contents
Open Table of Contents
- Overview of Modules and Packages in Python
- The
import
Statement Syntax - Importing Module Attributes Directly
- Import Aliasing with
as
- Importing Multiple Modules on One Line
- Importing All Objects from a Module with
*
- Importing Specific Objects from a Module
- Using
from module import
Syntax - Managing Module Namespaces with
as
- Relative Imports
- Importing Modules from Package Subdirectories
- Importing Built-in and Third-Party Modules
- Module Caching and Reloading
- Using
if __name__ == '__main__'
- Finding Modules and Reading Documentation
- Handling ImportErrors and Module Troubleshooting
- Conclusion
Overview of Modules and Packages in Python
In Python, code is organized into logical files called modules. Each module contains definitions and statements related to a specific topic, keeping code compartmentalized and modular.
Some key facts about Python modules:
- Modules are defined in
.py
files that contain reusable code. - Modules can define functions, classes, variables and other objects.
- Modules can import functionality from other modules.
- Module code executes on first import into a program.
- The
import
statement is used to access modules. - Modules make Python code maintainable by logical grouping.
A Python package is a collection of related modules in a folder structure that defines a namespace. Packages allow hierarchical organization of modules.
- Packages contain
.py
module files and a special__init__.py
file. - Package folder structure reflects the namespace hierarchy.
- The
__init__.py
file executes on package imports. - Packages allow organization of modules and control of visibility.
import
works on both modules and packages.
So in summary, modules encapsulate Python code for reuse, while packages organize and namespace related modules. We will focus specifically on importing modules in this guide.
The import
Statement Syntax
The main mechanism for accessing the contents of a module in Python is the import
statement. Here is its basic syntax:
import module_name
This imports the target module and makes its contents available in the current namespace.
Some things to note about import
:
module_name
is the name of module to import, without the.py
extension.- Modules must exist on the module search path to be importable.
import
executes all top level statements in the module on first import.- After import, the module’s attributes can be accessed using
module_name.attribute_name
dot notation. - Multiple
import
statements can be used to import multiple modules. import
statements are typically placed at the top of a file.
Let’s see a simple example importing a module:
# Import module
import mymodule
# Access a function from the imported module
mymodule.say_hello()
# Access a constant variable
print(mymodule.MODULE_NAME)
This demonstrates the core functionality of import
- making a module’s code available for use in the current program.
Now let’s explore some more advanced import techniques and syntax variations.
Importing Module Attributes Directly
When importing a module, you can directly access its attributes using the module name dot notation described above:
import mymodule
mymodule.say_hello()
x = mymodule.some_value
This allows your code to explicitly call out where attributes come from, making the source clear.
However, you can also set up imports so attributes are directly available without the module name prefix, like so:
from mymodule import say_hello, some_value
say_hello()
print(some_value)
Here we demonstrate from import
syntax, which we will cover in more detail later. This imports the specific say_hello() function and some_value variable directly into the global namespace.
In general, directly importing attributes is handy for commonly used functions or constants. But namespace pollution can occur if overused.
Import Aliasing with as
When importing a module, you can specify an alias using the as
keyword:
import mymodule as mm
mm.say_hello()
This allows you to rename the module reference to something shorter or more convenient.
Aliasing is also useful when importing multiple modules that have conflicting attribute names:
import pandas as pd
import matplotlib.pyplot as plt
Here we alias pandas
to pd
and matplotlib
to plt
to avoid overlap.
So import aliasing with as
provides control over the namespace and prevents naming collisions.
Importing Multiple Modules on One Line
It’s common to need functionality from several different modules. Instead of separate import
statements, you can import multiple modules on one line like this:
import module1, module2, module3
Or with aliases:
import pandas as pd, numpy as np, scipy as sp
This is convenient for reducing code clutter and importing related modules together.
Keep in mind it can reduce readability compared to one module per line. Also, if a module import fails, it will produce an error and stop further imports on that line.
Importing All Objects from a Module with *
You can import all attributes of a module using the *
syntax:
from mymodule import *
This imports all objects defined in mymodule
directly into the current namespace. This can be useful for modules that provide many useful attributes that you frequently access.
However, importing all module contents has downsides:
- It can cause namespace pollution by introducing many names.
- It’s unclear where attributes come from at the call site.
- Function/variable name conflicts can occur.
- The
__all__
list is ignored, which we’ll explain later.
So in general, importing specific objects is preferred for clarity and tooling support.
Importing Specific Objects from a Module
For finer control over what’s imported from a module, you can specify individual objects.
The basic syntax is:
from module_name import object1, object2, ...
For example:
from math import cos, pi
print(cos(pi))
This imports just the cos()
and pi
attributes from the math
module.
You can import objects into an aliased module name using:
from module_name import object1 as name1, object2 as name2
Advantages of selectively importing objects:
- Avoids namespace pollution by only importing needed attributes.
- Makes it clear where each object comes from.
- Helps control visibility by only exposing specific objects.
- Can result in faster import times for large modules.
This provides precision control over what’s imported from a module.
Using from module import
Syntax
The from module import
syntax shown above is very convenient for importing specific module contents. Here are some key points:
- Omits the module name on usage -
cos(pi)
rather thanmath.cos(math.pi)
. - Imports only specified objects rather than everything.
- Allows renaming imports with
as
. - Executes faster since returned objects are cached.
- Can lead to namespace collisions since names are unscoped.
Overall, from import
provides fast access to just the objects you need from a module. But overuse can lead to namespace issues, so it should typically be constrained to selective imports.
Managing Module Namespaces with as
As mentioned above, when importing module objects directly, name collisions can occur due to lack of namespacing.
For example:
from module1 import my_function
from module2 import my_function
This results in an error due to duplicate my_function
names.
To avoid this, we can import the objects into differently named namespaces using as
:
from module1 import my_function as mf1
from module2 import my_function as mf2
Now the functions are uniquely named and import properly.
This technique is highly recommended when importing objects directly to prevent overlaps.
Relative Imports
When modules are structured as part of a package, you can use relative imports to access sibling modules at the same level.
For example, consider a mypackage
package with modules module1.py
, module2.py
, and main.py
:
mypackage/
module1.py
module2.py
main.py
Inside main.py
, we can import module1
using a relative import:
from . import module1
The .
indicates look for the module in the same package directory rather than on the normal path.
Some key points about relative imports:
- Use dot notation
.
to specify relative imports. - Modules must be structured as a package to work.
- Absolute imports are still possible by using normal import syntax.
- Relative imports can reference sibling modules or parent packages.
- The
__init__.py
defines what symbols are exported from the package. - Relative imports help encapsulate internal module structure.
When leveraged properly, relative imports provide a clean way to access internally defined modules in a structured, encapsulated manner.
Importing Modules from Package Subdirectories
Larger packages often split up modules into subdirectories to organize related code.
You can import modules located in package subdirs using dot notation in the from
statement:
from .subpackage1 import module1
from .subpackage2.module2 import func2
This allows arbitrary directory structures to be represented in a modular, importable way.
Some key points:
- Use dots to denote navigating into subdirectories.
- Omit the final directory when importing a full submodule.
- This only works for modules defined as packages.
- Helps avoid long, repetative import paths.
- Subdir modules must be suitably imported into parent
__init__.py
.
Overall, importing subdirectory modules helps reduce code duplication and allows large packages to segment code logically.
Importing Built-in and Third-Party Modules
Beyond your own modules and packages, Python comes batteries included with many built-in modules available right out of the box, such as math
, random
, datetime
, and many more.
You can import built-in modules just like your own:
import math
import random
import datetime
Additionally, there is a vast ecosystem of third-party packages on PyPI that can be installed and imported:
import pandas
import matplotlib
import scipy
Some key points about external modules:
- Built-in modules come with every Python installation.
- Third-party modules must be installed via
pip
or other means. - Both built-ins and third-party modules use normal
import
syntax. - Many standard library and third-party docs show import examples.
- Be sure to handle ImportError exceptions when importing.
Leveraging built-in and third-party modules helps reduce reinventing the wheel while building on mature, well-tested Python codebases developed by the community.
Module Caching and Reloading
Python caches previously imported modules and reuses them on subsequent imports rather than reloading. This improves performance by only executing the code once.
Caching does have implications you should be aware of:
- Code in the module top level executes only on first import.
- Function/class definitions are fixed after first import.
- Reloading allows picking up module changes dynamically.
- Reimports reference the cached module objects.
- Caching avoids expensive file I/O and reparsing on each import.
To force reloading, use imp.reload(module)
or simply reload(module)
in Python 2.x. But take caution, as this can lead to unpredictable behavior for already loaded modules.
Understanding import caching helps explain module reloading and when repeated imports reference the same object.
Using if __name__ == '__main__'
A common practice in reusable modules is using a code block like:
if __name__ == '__main__':
# code here
This allows the module to execute more code when run directly vs imported.
The __name__
variable is set to:
__main__
when run as main program.- The module name when imported.
This can be used to include test code, demo routines, or anything else that shouldn’t execute on import.
Placing imports, constants, function/class definitions outside this block allows them to be reused when the module is imported.
Proper use of if __name__ == '__main__'
provides encapsulation and reusability of modules.
Finding Modules and Reading Documentation
As you utilize more modules in your code, here are some tips for finding and learning about them:
- Tab complete module names in IDEs/editors to find built-ins.
- Browse the Python Standard Library docs for built-in modules.
- Search PyPI for third-party packages.
- Check repos like GitHub for custom modules.
- Use Google along with site:docs.python.org to search docs.
- View module source code directly for details.
- Read module documentation strings and inline comments.
- Experiment interactively in the REPL.
Gaining visibility into available modules along with reading docs helps familiarize yourself with Python’s extensive set of code reuse options.
Handling ImportErrors and Module Troubleshooting
When importing modules, ImportError
exceptions can occur for several reasons:
- Module name is invalid or misspelled. Double check spelling.
- Module file doesn’t exist or can’t be found. Check module search path.
- Dependency module is missing. Install required modules.
- Circular import dependency exists. Restructure code.
- Runtime error occurs in module code. Fix bug in module.
Some troubleshooting tips:
- Catch
ImportError
specifically to handle issues gracefully. - Print the module search path to check for module availability.
- Eliminate naming confusion with aliases if required.
- Use absolute rather than relative imports.
- Check
sys.modules
contains expected modules. - Remove cached modules from
sys.modules
for fresh imports.
Carefully handling import issues leads to robust code able to gracefully recover when module dependencies are not met.
Conclusion
We have covered a wide range of techniques for importing modules and packages in Python. Here are some key takeaways:
import
makes code in external modules available in your programs.from
allows convenient access to specific objects from a module.- Aliases can be used to manage namespace conflicts.
- Modules and packages help organize related Python code.
- Relative imports reference internal package modules.
- Many built-in and third-party modules are available.
- Modules are cached on first import for efficiency.
- Read module documentation and source for usage examples.
- Carefully handle
ImportError
exceptions.
With structured use of modules and packages, you can write Python programs that are well-organized and leverage code reuse rather than reinventing the wheel. Mastering these import techniques will help set you on the path to efficiently developing robust and maintainable Python software applications.