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:

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:

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.