Python from import: Syntax and Behavior
python from import: Learn how the from ... import statement works in Python, including syntax, namespace behavior, aliasing, relative imports, and common mistakes.
The from ... import ... statement is a core part of Python's import system. Understanding python from import is essential for writing clean module-based code. This statement binds a name from a module directly into the current namespace, allowing you to use that name without the module prefix.
The from import Syntax
The basic form is:
from math import sqrt
This binds sqrt to the function math.sqrt in the current scope. After this statement, you can call sqrt(16) directly instead of math.sqrt(16). The module name math itself is not bound, so referencing math would raise a NameError.
You can import multiple names in one statement:
from os import path, getcwd
You can also import a submodule or attribute that is nested, such as from package.module import function.
How It Differs from import module
Using import module binds the module name itself, so you must qualify names with the module prefix:
import math print(math.sqrt(16))
With from math import sqrt, you skip the prefix. This is convenient for frequently used functions, but it also means the name is copied into the current namespace. If you later assign a new value to sqrt, you only change the local binding, not the original function in math.
The choice affects readability and namespace pollution. import math makes it clear where the function comes from when you read math.sqrt. from import is shorter but can obscure the origin of a name if many names are imported from different modules.
Namespace and Binding Behavior
When you execute from module import name, Python looks up name in the module's namespace and binds it to the current scope. The binding is a reference to the object, not a copy. If the module later changes that attribute, the imported name still refers to the original object. For example:
# module_a.py value = 10
from module_a import value import module_a module_a.value = 20 print(value) # still 10
This behavior matters when you import mutable objects. If you import a list and then mutate it, the mutation is visible in the original module. But if you reassign the imported name, you break the connection.
Aliasing with as
You can rename an imported name using as:
from datetime import datetime as dt
This is useful when the original name is long, conflicts with another name, or you want to give it a shorter alias in your code. Aliasing also works with import module as alias, but the syntax differs.
Common patterns include:
import numpy as np from pandas import DataFrame as df
Aliasing does not change the object; it only changes the local binding.
Importing All Names with * and all
The from module import * form imports all names that do not start with an underscore, unless the module defines __all__. If __all__ is present, only the names in that list are imported.
# module_b.py __all__ = ['public_func', 'public_var']
from module_b import *
Using * can pollute the namespace and make code harder to read, especially when importing from multiple modules. It is generally discouraged in production code except in interactive sessions or when a module explicitly defines __all__ to control its public interface.
Relative Imports in Packages
Inside a package, you can use relative imports with dots:
from . import sibling_module from .submodule import function from ..parent_module import name
A single dot refers to the current package, two dots to the parent package, and so on. Relative imports only work inside a package, not in a standalone script. They are useful for organizing code into submodules without hardcoding the top-level package name.
Common Mistakes and Pitfalls
One frequent mistake is assuming that from import gives you a live reference to the module attribute. As shown earlier, reassigning the module attribute does not update the imported name. If you need to always see the current value, import the module itself and access the attribute each time.
Another issue is circular imports. If two modules import each other using from ... import ..., the import may fail because the module is not fully initialized. This can be avoided by restructuring code or using import module inside functions.
Also, be careful with name conflicts. Importing from module import open overrides the built-in open. This can cause subtle bugs.
Performance and Maintainability Considerations
From a performance perspective, from import and import have similar costs because both load the module once. The difference is in attribute lookup: math.sqrt requires a dictionary lookup each time, while a directly imported name is a local variable lookup, which is slightly faster. However, this is rarely a bottleneck.
The more important consideration is maintainability. Using import module keeps the origin of each name explicit, which helps when reading code. from import can make it harder to trace where a name came from if you import many names from different modules. Use it judiciously for frequently used functions or when the module name is long.