Skip to main content

Python Import Statement: Load Modules Effectively

The import statement is the gateway to accessing code from Python's standard library, third-party packages, and your own modules. Understanding the different import styles and best practices is essential for writing clean, maintainable code that reuses existing functionality effectively.


What Is the Import Statement?

The import statement brings code from one module into your current namespace, giving you access to functions, classes, and variables defined elsewhere. Python's import system is one of its greatest strengths—it lets you use thousands of pre-built modules without rewriting common functionality. There are multiple ways to import, each with different tradeoffs between clarity and conciseness.


How Do You Perform a Standard Import?

The most straightforward and safest way is to import an entire module using the import keyword. This keeps the module's contents in a separate namespace, making it clear where each function comes from.

# Example: importing the math module
import math

# Access functions and constants with the module prefix
pi_value = math.pi
square_root = math.sqrt(25)

print(f"The value of pi is: {pi_value}")
print(f"The square root of 25 is: {square_root}")

# Output:
# The value of pi is: 3.141592653589793
# The square root of 25 is: 5.0

This pattern is explicit and safe—anyone reading your code immediately sees that pi and sqrt come from the math module. It also prevents accidental name collisions when multiple modules define similarly named functions.


How Do You Import Specific Names with from ... import?

When you only need one or two items from a module, the from ... import statement lets you bring specific functions or classes directly into your namespace without the module prefix.

# Import only specific items from math module
from math import sqrt, pi

# Now use them directly without the module name prefix
pi_value = pi
square_root = sqrt(25)

print(f"The value of pi is: {pi_value}")
print(f"The square root of 25 is: {square_root}")

This is more concise, but it can be less clear where items originate if you're reading code without looking at imports. Use this style when the source is unambiguous or when working with well-known modules where developers expect direct access (like from os import path).


How Do You Use Aliasing with the as Keyword?

The as keyword creates an alias—an alternate name—for a module or imported item. This is invaluable when dealing with long names or following community conventions.

# Alias a module with a shorter name
import math as m

# Alias when importing specific items
from math import sqrt as square_root

pi_value = m.pi
result = square_root(25)

print(f"Pi = {pi_value}, sqrt(25) = {result}")

Aliasing is extremely common in data science, where libraries have conventional shortened names:

# Standard aliases used by the Python community
import numpy as np # NumPy arrays and math
import pandas as pd # Data manipulation
import matplotlib.pyplot as plt # Plotting

These conventions are so widely used that developers expect to see np.array() rather than numpy.array(). Following these conventions makes your code instantly familiar to others.


What Are Import Best Practices?

How you organize imports affects code readability and maintainability. Python's official style guide (PEP 8) recommends specific import ordering and patterns.

Import Order (PEP 8 Standard)

Structure imports at the top of your file in this order:

  1. Standard Library imports — modules bundled with Python (os, sys, math, datetime)
  2. Third-party library imports — external packages installed via pip (requests, numpy, pandas)
  3. Local application/module imports — your own project code

Separate each group with a blank line:

# Standard library
import os
import sys
from datetime import datetime

# Third-party libraries
import requests
import pandas as pd

# Local application modules
from my_project.utils import helper_function
from . import local_module

Avoid Wildcard Imports

Never use wildcard imports (from module import *). While tempting, they pollute your namespace and hide where names originate:

# DON'T DO THIS
from math import *

# Now: where did pi and sqrt come from? Not obvious without knowing math module contents.
print(pi)
print(sqrt(25))

Problems with wildcard imports:

  • Hidden sources: You can't tell where pi or sqrt come from without reading the module documentation
  • Name collisions: If you already had a variable named pi, the import silently overwrites it, causing subtle bugs
  • IDE confusion: Autocomplete and static analysis tools can't help effectively

Always be explicit:

# GOOD: clear origin
import math

# GOOD: explicit items only
from math import sqrt, pi

Circular Import Awareness

Avoid situations where module A imports module B, and module B imports module A. This causes circular import errors. If you encounter circular imports, restructure your code or move the import inside a function (local import) to delay evaluation.

# file_a.py
from file_b import function_b # Circular import risk

def function_a():
pass

# file_b.py
from file_a import function_a # Circular import

def function_b():
pass

Solution: Use local imports when necessary:

# file_b.py
def function_b():
from file_a import function_a # Import only when needed
return function_a()

Key Takeaways

  • import module is the safest, most explicit approach; access items via module.name
  • from module import name is more concise when importing 1-2 items, but origin is less obvious
  • import module as alias handles long names and follows community conventions (e.g., numpy as np)
  • Order imports: Standard library first, then third-party, then local code
  • Never use from module import *—it hides origins and causes namespace pollution and potential name collisions
  • Circular imports cause runtime errors; avoid or use local imports to defer evaluation

Frequently Asked Questions

What is the difference between import math and from math import sqrt?

import math loads the entire module and requires you to use the prefix (math.sqrt(25)). from math import sqrt brings only sqrt into your current namespace (sqrt(25)). Use the first for modules you use extensively; use the second when importing only 1-2 specific items.

Why do data scientists write import pandas as pd instead of import pandas?

Community convention reduces typing and improves readability for experienced developers. Everyone expects pd.DataFrame() in data science code. Following these standards—np for NumPy, plt for matplotlib—makes your code instantly recognizable and easier for teammates to read.

Can I import the same module twice?

Python caches module imports. If you import math twice in the same script, Python only loads it once. Subsequent imports return the cached module, so this is safe and has no performance penalty.

What happens if I import a module inside a function?

Local imports (inside functions) work fine and are sometimes used intentionally to avoid circular imports or delay loading heavy modules. However, they're slower on repeated calls since Python checks the cache each time. Use local imports sparingly, typically only to resolve circular dependencies.

How do I know what's available in a module?

Use the dir() function to list all public names in a module:

import math
print(dir(math)) # Lists all attributes and functions

Or use help() to see documentation:

import math
help(math.sqrt) # Shows detailed help for a function

Further Reading