How to import modules, packages, functions, etc. in Python

Modified: | Tags: Python

In Python, the import statement allows you to access standard library modules, pip-installed packages, your own custom packages, and more.

For details on the module search path, refer to the following article:

Modules, packages, and libraries in Python

Modules

In Python, a module is simply a file that contains definitions and declarations of functions, classes, and so on.

Packages

A directory containing modules and an __init__.py file is known as a "regular package". __init__.py can be empty.

From Python 3.3, a directory without __init__.py can be treated as a package. Such a package is called a "namespace package".

Libraries

Although not strictly defined, packages and modules are sometimes called libraries.

Basic usage of import

For example, import the math module.

Using import <module_name>, a module is imported as an object of the module type. You can check which file is imported with print(<module_name>).

import math

print(type(math))
# <class 'module'>

print(math)
# <module 'math' from '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/math.cpython-37m-darwin.so'>

You can access functions and constants defined in the module using the syntax <module_name>.<function_name> or <module_name>.<constant_name>.

print(math.radians(180))
# 3.141592653589793

print(type(math.radians))
# <class 'builtin_function_or_method'>

print(math.pi)
# 3.141592653589793

print(type(math.pi))
# <class 'float'>

Note that radians() is a function that converts degrees to radians, and pi is a constant representing the mathematical constant pi.

To directly use functions or variables from a module, employ the from keyword as described below. Please be aware that using import <module_name>.<function_name> would result in an error.

PEP8 recommendations for import

PEP8, the Python style guide, provides recommendations on how to write the import statement.

Keep in mind that PEP8 is a style guide; deviating from it won't cause your code to throw errors.

Import multiple modules

While it's possible to import multiple modules in a single import statement by separating them with commas, PEP8 discourages this practice. Instead, it recommends each import statement to be on a separate line.

# Wrong:
import os, sys

# Correct:
import os
import sys

When importing functions, variables, classes, etc., using the from keyword, you can list multiple items separated by commas.

from math import pi, radians

Order of modules

PEP8 recommends that imports should be grouped and arranged in the following order, with a blank line separating each group:

  1. Standard libraries
  2. Third party libraries
  3. Local libraries

While not explicitly stated in PEP8, it's a common practice to sort each group's modules alphabetically.

import math
import os
import sys

import Requests

import my_package1
import my_package2

Import functions, variables, classes, etc.: from ... import ...

The from ... import ... syntax enables you to specifically import functions, variables, classes, etc., from a module.

Import a single item

The from <module_name> import <identifier_name> syntax allows you to import specific items. The imported items can be directly used via <identifier_name>. Note that the module itself is not imported, and trying to access unimported items will result in a NameError.

from math import pi

print(pi)
# 3.141592653589793

# print(math.radians(180))
# NameError: name 'math' is not defined

Import multiple items at once

You can import multiple items from the same module at once by listing them, separated by commas.

from math import pi, radians

print(pi)
# 3.141592653589793

print(radians(180))
# 3.141592653589793

If the line gets too long, you can use parentheses () to split it across multiple lines.

from math import (
    e,
    exp
)

print(e)
# 2.718281828459045

print(exp(1))
# 2.718281828459045

Here, e represents Euler's number, and exp() is the exponential function. Please see the following article for more details:

The * operator can be used to import all items defined in a module.

from math import *

print(pi)
# 3.141592653589793

print(cos(0))
# 1.0

print(sin(0))

If the __all__ variable is defined in a module, only the identifiers listed in __all__ will be imported.

Note that PEP8 discourages the use of * for imports as it can lead to ambiguity about which names exist in the namespace.

Import with an alias: import ... as ...

The as keyword allows you to assign an alias when importing. Note that once an alias is assigned, you must use the alias instead of the original name.

Here's an example of aliasing a module:

import math as m

print(m.pi)
# 3.141592653589793

# print(math.pi)
# NameError: name 'math' is not defined

And aliasing a variable:

from math import pi as PI

print(PI)
# 3.141592653589793

# print(pi)
# NameError: name 'pi' is not defined

Certain libraries, such as NumPy and pandas, are conventionally imported with abbreviated names:

import numpy as np
import pandas as pd

Import from packages

When importing modules from a package, the correct method may vary depending on the package's structure and __init__.py. Generally, the package's documentation will guide you on the correct approach.

Here are some examples to demonstrate the various patterns.

urllib

Let's start with urllib, a module from the standard Python library.

The urllib directory contains several module files and an empty __init__.py, as shown below:

urllib/
├── __init__.py
├── error.py
├── parse.py
├── request.py
├── response.py
└── robotparser.py

Simply using import urllib doesn't provide access to its internal modules. For example, attempting to access urllib.error would result in an AttributeError.

import urllib

print(type(urllib))
# <class 'module'>

print(urllib)
# <module 'urllib' from '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/__init__.py'>

# print(urllib.error)
# AttributeError: module 'urllib' has no attribute 'error'

To access the modules, you need to explicitly import them using import <package_name>.<module_name>.

import urllib.error

print(urllib.error)
# <module 'urllib.error' from '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/error.py'>

print(urllib.error.HTTPError)
# <class 'urllib.error.HTTPError'>

Alternatively, you can use from <package_name> import <module_name>.

from urllib import error

print(error)
# <module 'urllib.error' from '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/error.py'>

print(error.HTTPError)
# <class 'urllib.error.HTTPError'>

It is also possible to specify and import a class defined in the module.

from urllib.error import HTTPError

print(HTTPError)
# <class 'urllib.error.HTTPError'>

Note that if there is no initialization code in __init__.py, as in this case, you must explicitly import the submodules.

If you are using IPython/Jupyter Notebook, you may notice that importing urllib does allow you to use urllib.parse. This behavior is due to the IPython startup process.

collections

Let's consider a different example with the collections module.

The collections directory consists of the following:

collections/
├── __init__.py
└── abc.py

In collections, classes like Counter and OrderedDict are defined in __init__.py rather than stored as separate module files like in urllib.

In such cases, after importing a package, you can access a class using <package_name>.<class_name>.

import collections

print(collections)
# <module 'collections' from '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/collections/__init__.py'>

print(collections.Counter)
# <class 'collections.Counter'>

However, you cannot directly import classes using import <package_name>.<class_name>.

# import collections.Counter
# ModuleNotFoundError: No module named 'collections.Counter'

You can import classes with from.

from collections import Counter

print(Counter)
# <class 'collections.Counter'>

NumPy

Let's consider NumPy, an example of a third-party library:

In NumPy, each sub-package is imported in __init__.py in the numpy directory.

You don't need to import each module individually. Just writing import numpy as np enables the use of various functions.

scikit-learn

The case of scikit-learn is different.

It does not import sub-packages in __init__.py in the sklearn directory.

You need to import the sub-packages explicitly, as follows.

from sklearn import datasets, model_selection, svm, metrics

ModuleNotFoundError

This error indicates that the module cannot be found.

ModuleNotFoundError: No module named 'xxx'

The issue might be an incorrect module name or a problem with the module search path.

As shown in the example of collections above, ModuleNotFoundError can also occur if you attempt to import a class instead of a module. In such cases, use from to import a function or a class.

AttributeError

This error indicates that the imported module does not have the specified attribute.

AttributeError: module 'xxx' has no attribute 'yyy'

This might happen when the correct file is not imported.

For example, when you use import <module_name>, the Python interpreter first looks for a module with that name in the same directory as the currently executed script file. If it finds a file named <module_name>.py in that directory, it imports that file.

Use print(<module_name>) to verify if the file is imported from the expected location. If the imported file isn't the one you intended to import, you may need to rename or move the conflicting file.

Related Categories

Related Articles