Import * in Python- What It Means and When to Use It
What Does import * Actually Do?
When you write from module import * in Python, you're telling Python to pull in every public name defined in that module. No exceptions. No filters. Just all of it.
Here's the thing though—"public" has a specific meaning here. Python uses the __all__ list to determine what counts as public. If a module defines __all__ = ['func1', 'func2'], then import * only brings in func1 and func2. Everything else stays hidden.
If there's no __all__ list, Python defaults to importing everything that doesn't start with an underscore.
Why People Use It
The main reason developers reach for import * is convenience. Less typing. Cleaner imports at the top of a file. You can call sqrt() directly instead of math.sqrt().
Some people also use it when exploring code in a REPL session. Pull in everything, mess around, figure out what's available. That's fine for throwaway exploration.
Why You Should Think Twice
Here's where things get messy. When you do from module import *, you have no idea what names are now in your namespace. You might accidentally overwrite a variable. You might create a naming conflict that takes hours to debug.
Consider this disaster:
from math import *
from cmath import *
# What is sqrt now? math.sqrt or cmath.sqrt?
# Depends on import order. Good luck debugging this.
Python won't warn you. It just silently overwrites names based on import order. This is the kind of bug that shows up in production at 2 AM.
Another problem: readability. When someone reads your code and sees sqrt(), they have no idea where it came from. They have to scroll up to the imports, if they're even there. That's a waste of time.
When Import * Might Be Acceptable
Almost never in production code. But there are a couple of legitimate cases:
- Quick prototyping in notebooks or REPL sessions where you're just testing ideas
- Custom modules where you're the only developer and you control what
__all__exports - Implicit submodule re-exports in
__init__.pyfiles where you're intentionally exposing a flat namespace
The Proper Way to Import
Just import what you need. That's it. Full stop.
# Do this instead
from math import sqrt, pi
# Or this
import math
# Either way, you know exactly what's available
result = math.sqrt(16) # Clear origin
area = pi * r**2 # No mystery
This approach gives you:
- Explicit dependencies
- No namespace pollution
- Better IDE support (autocomplete actually works)
- Easier debugging
How to Control What Import * Exports
If you're building a module and you want import * to behave correctly, define __all__:
# mymodule.py
__all__ = ['useful_func', 'UsefulClass']
class UsefulClass:
pass
class _InternalHelper: # Won't be imported with *
pass
def useful_func():
pass
def _private_helper(): # Also won't be imported with *
pass
Now anyone using from mymodule import * only gets what you explicitly allow. This is good practice even if you expect people to use explicit imports.
Import * in the Wild
Some modules are designed around import *. The pprint module does this. The antigravity easter egg does this. It's not inherently evil—but it should be a deliberate design choice, not lazy habit.
The Bottom Line
Use import * when you're prototyping. Use it in throwaway scripts. Use it when exploring an unfamiliar module in a REPL.
Don't use it in code that other people will read, maintain, or deploy. The namespace pollution isn't worth the three characters you save typing from module import specific_name.
Your future self will thank you. So will the developer who inherits your code.