I'm trying to run some logic when objects are imported from a module by using __getattr__
as described here: __getattr__ on a module
...but the logic runs twice. Why is that happening and how can I stop it?
main.py
from test import x, y
test.py
def __getattr__(name: str):
print(f"Imported {name}")
Your __getattr__
returns None
for all attributes, including __path__
, and if a module has a __path__
attribute, it's treated as a package.
For a package, from test import x, y
needs to handle possible submodules named test.x
and test.y
. The code that does this handling uses hasattr
first, to test whether test
already has x
and y
attributes:
elif not hasattr(module, x):
...
and that hasattr
is responsible for the first __getattr__('x')
and __getattr__('y')
calls.
The second __getattr__('x')
and __getattr__('y')
calls are just the ones you'd expect to happen, to retrieve test.x
and test.y
for the import.
Your __getattr__
shouldn't return a value for special attributes like __path__
.
Also, unrelated, naming a module test
is a bad idea, because the standard library already claimed that name for Python's own test suite.