Question

What __all__ Means in Python: A Beginner-Friendly Guide

pythonsyntaxnamespacespython-import

Question

I often see __all__ inside Python __init__.py files. What does __all__ do, and how does it affect imports?

Short Answer

By the end of this page, you will understand what __all__ means in Python, why it is commonly used in __init__.py files, how it affects from module import *, and when you should or should not use it in real projects.

Concept

__all__ is a special Python variable used to define a module's public interface.

It is usually a list of strings:

__all__ = ["name1", "name2", "name3"]

Each string is the name of a variable, function, class, or submodule that Python should treat as publicly exportable.

The main place where __all__ matters is this kind of import:

from mymodule import *

If mymodule defines __all__, then only the names listed in __all__ are imported.

If mymodule does not define __all__, then import * usually imports all names that do not start with an underscore.

Why this matters

In real programs, a module may contain:

  • public functions you want other developers to use
  • helper functions meant to stay internal
  • constants, classes, and implementation details

__all__ lets you say:

  • "These names are part of the public API"
  • "Everything else is internal"

This is especially useful in __init__.py because packages often re-export selected names from submodules.

Common package example

# mypackage/__init__.py
from .math_utils import add, subtract
from .string_utils import capitalize_words

__all__ = ["add", "subtract", "capitalize_words"]

Now this works predictably:

from mypackage import *

Only add, subtract, and capitalize_words are imported.

Important note

__all__ does not make names private or secure. It only controls what gets imported with import * and helps communicate intended public names.

A user can still directly access other names if they know them:

from mypackage.math_utils import _internal_helper

So __all__ is about API design and import behavior, not access control.

Mental Model

Think of a Python module like a shop.

  • Everything inside the shop exists.
  • But the shop window shows only selected items.
  • __all__ is the list of items placed in the window.

When someone does:

from shop import *

They only get what is displayed in the window.

Without __all__, Python makes a best guess and usually shows everything that does not begin with _.

So __all__ is like a curated display of the names a module wants to present publicly.

Take Quiz

Syntax and Examples

The basic syntax is:

__all__ = ["name1", "name2"]

Example 1: Module-level __all__

# tools.py

def greet(name):
    return f"Hello, {name}!"


def add(a, b):
    return a + b


def _debug_message():
    return "debug info"


__all__ = ["greet", "add"]

Now:

from tools import *

print(greet("Sam"))
print(add(2, 3))

The names greet and add are imported, but _debug_message is not.

Example 2: Without __all__

# tools.py

def greet(name):
    return f"Hello, {name}!"


def add(a, b):
    return a + b


def _debug_message():
    return "debug info"

Then:

from tools import *

Usually imports:

  • greet
  • add

But not _debug_message, because it starts with _.

Example 3: In __init__.py

# mypackage/__init__.py
from .users import create_user
from .auth import login

__all__ = ["create_user", "login"]

This allows the package to expose a cleaner top-level API:

from mypackage import create_user, login

Instead of making users import from many internal files.

Good practice

Even though import * exists, most Python code prefers explicit imports:

from tools import greet, add

This is clearer and avoids namespace confusion.

Step by Step Execution

Consider this file:

# helpers.py

def public_function():
    return "I am public"


def another_public_function():
    return "Me too"


def _internal_function():
    return "I am internal"


__all__ = ["public_function"]

Now run:

from helpers import *

Step by step:

  1. Python loads the helpers module.

  2. It sees three function names:

    • public_function
    • another_public_function
    • _internal_function
  3. It also sees:

    __all__ = ["public_function"]
    
  4. Because __all__ exists, Python uses that list for import *.

  5. Only public_function is imported into the current namespace.

  6. another_public_function is not imported, even though it does not start with _.

  7. _internal_function is also not imported.

After that:

print(public_function())

works.

But this would fail if you expected it from import *:

print(another_public_function())

because it was not included in __all__.

However, direct import still works:

from helpers import another_public_function
print(another_public_function())

So __all__ controls wildcard imports, not whether a name exists.

Real World Use Cases

1. Creating a clean package API

A package may have many internal files, but you want users to import from one simple place.

from mypackage import connect, disconnect

You can re-export those names in __init__.py and define them in __all__.

2. Hiding helper functions from wildcard imports

A module may contain utility code that should not appear as part of the public API.

def process_data(data):
    ...


def _normalize(data):
    ...

Using __all__ helps ensure only intended names are exposed with import *.

3. Building libraries for other developers

If you are writing a reusable package, __all__ helps communicate which names are stable and meant for external use.

4. Organizing large codebases

Larger projects often split features into submodules, then expose a small curated API at the package level.

5. Improving readability in interactive use

In notebooks or REPL sessions, wildcard imports are sometimes used for convenience. __all__ makes those imports more controlled.

Take Quiz

Real Codebase Usage

In real codebases, __all__ is most often used as part of API design, not as a daily feature in every file.

Common patterns

Re-exporting selected names

# package/__init__.py
from .client import Client
from .errors import APIError
from .utils import format_date

__all__ = ["Client", "APIError", "format_date"]

This creates a cleaner package surface.

Separating public and internal helpers

def parse_config(path):
    ...


def _read_file(path):
    ...


__all__ = ["parse_config"]

Stabilizing a library API

Developers may change internal functions freely while trying to keep the names in __all__ stable for users.

Patterns often used alongside __all__

  • Underscore prefixes like _helper for internal names
  • Explicit imports instead of import *
  • Package-level exports in __init__.py
  • Clear module boundaries so public code is easy to find

What experienced developers usually do

  • Use __all__ in libraries and packages where API clarity matters
  • Avoid relying heavily on from module import * in application code
  • Prefer explicit imports for readability and maintainability

Common Mistakes

Mistake 1: Thinking __all__ makes things private

Broken assumption:

__all__ = ["public_function"]

Some beginners think this prevents access to other names. It does not.

This still works:

from helpers import _internal_function

Avoid it

Treat __all__ as a public API hint and wildcard import control, not security.

Mistake 2: Forgetting that strings must match real names

Broken code:

def greet():
    return "hi"

__all__ = ["great"]

great is misspelled. The export list should contain actual names.

Correct version:

def greet():
    return "hi"

__all__ = ["greet"]

Mistake 3: Using import * everywhere

Broken style:

from tools import *

This can make code harder to read because you cannot easily tell where names came from.

Better

from tools import greet, add

Mistake 4: Assuming underscore names are truly hidden

A leading underscore is only a naming convention.

def _helper():
    return 42

It signals "internal use," but Python still allows access.

Mistake 5: Forgetting to update __all__

If you add a new public function but forget to include it, wildcard imports and public API expectations may become inconsistent.

Mistake 6: Putting objects instead of strings in __all__

Broken code:

__all__ = [greet, add]

Correct code:

__all__ = ["greet", "add"]

Comparisons

ConceptWhat it doesMain useImportant note
__all__Lists public names for wildcard importControl from module import *Uses strings of names
Leading underscore (_name)Marks a name as internal by conventionSignal "not public"Not enforced privacy
Explicit importImports specific namesClear, readable codeUsually preferred
import *Imports many names into current namespaceConvenience in limited casesCan reduce clarity

__all__ vs underscore prefix

  • _helper is a convention for internal use.
  • __all__ is an explicit export list.
  • They are often used together.

__all__ vs explicit imports

from tools import greet, add

This is usually better than:

from tools import *

Why?

  • clearer source of names
  • easier maintenance
  • fewer accidental name conflicts

__all__ in modules vs packages

  • In a module, __all__ controls which names wildcard import brings in.
  • In a package __init__.py, it often defines the package's public top-level exports.
Take Quiz

Cheat Sheet

__all__ = ["name1", "name2", "name3"]

Quick rules

  • __all__ is a list of strings.
  • It defines the public names for from module import *.
  • It is commonly used in __init__.py.
  • It does not make names private.
  • Without __all__, import * usually imports names that do not start with _.

Typical example

# mymodule.py

def public_func():
    pass


def _helper():
    pass


__all__ = ["public_func"]

Best practice

  • Use __all__ when designing a clear public API.
  • Prefer explicit imports in normal code.
  • Use _name for internal helpers by convention.

Common edge cases

  • Misspelled names in __all__ cause problems.
  • __all__ must contain strings, not function objects.
  • Direct imports can still access names not listed in __all__.

FAQ

What is __all__ used for in Python?

It defines which names are exported when someone uses from module import *.

Does __all__ make functions private?

No. It does not enforce privacy or security. It only affects wildcard imports and documents intended public names.

Why is __all__ often placed in __init__.py?

Because packages use __init__.py to expose a clean top-level API and re-export selected names from internal modules.

Do I need __all__ in every Python file?

No. It is helpful when you want to define a clear public API, especially in reusable modules and packages.

What happens if __all__ is missing?

With from module import *, Python usually imports names that do not start with _.

Should I use from module import *?

Usually no. Explicit imports are clearer and easier to maintain.

Can __all__ include classes and constants too?

Yes. It can include any publicly exported names, such as functions, classes, constants, or submodules.

Take Quiz

Mini Project

Description

Create a small Python package that exposes only a few public functions while keeping helper functions internal. This demonstrates how __all__ and __init__.py work together to create a clean package API.

Goal

Build a package where users can import only the intended public functions from the top level.

Requirements

  • Create a package folder with an __init__.py file.
  • Add one module with public functions and one internal helper function.
  • Re-export the public functions from __init__.py.
  • Define __all__ so wildcard imports expose only the intended names.
  • Show a short script that imports and uses the package.
Take Quiz

Keep learning

Related questions

View more