Why does importing package module #2 from package module #1 import all attributes of module #2 in the namespace?

15 hours ago 1
ARTICLE AD BOX

Consider a folder containing a simple python package:

python ├── main.ipynb ├── package │   ├── __init__.py │   ├── function.py │   └── operations.py ├── pyproject.toml ├── README.md └── uv.lock

where the modules in the package are

# function.py from package.operations import my_add, my_multiply def my_function(alpha, beta, x, y): return my_add(my_multiply(alpha, x), my_multiply(beta, y))

and

# operations.py def my_add(x, y): return x + y def my_multiply(x, y): return x * y

From main.ipynb, I run the import command

from package.function import my_function, my_add

This works, and both my_function and my_add are loaded into the namespace, even though my_add is defined in operations.py, not in function.py.

Why does this occur and is this something to be avoided?

I'm guessing this occurs because when package.function is imported, it runs the imports in function.py which are then added to the namespace. But it feels vaguely dangerous to me to allow the import of my_add directly from function.py, because it's not where it's defined. It seems to be breaking some of the protection against name collision that modularity is supposed to provide.

In any case, what is the best practice in a situation like this one?

Read Entire Article