Asked By – Matt Joiner
How can implement the equivalent of a
__getattr__ on a class, on a module?
When calling a function that does not exist in a module’s statically defined attributes, I wish to create an instance of a class in that module, and invoke the method on it with the same name as failed in the attribute lookup on the module.
class A(object): def salutation(self, accusative): print "hello", accusative # note this function is intentionally on the module, and not the class above def __getattr__(mod, name): return getattr(A(), name) if __name__ == "__main__": # i hope here to have my __getattr__ function above invoked, since # salutation does not exist in the current namespace salutation("world")
matt@stanley:~/Desktop$ python getattrmod.py Traceback (most recent call last): File "getattrmod.py", line 9, in <module> salutation("world") NameError: name 'salutation' is not defined
Now we will see solution for issue: __getattr__ on a module
A while ago, Guido declared that all special method lookups on
new-style classes bypass
__getattribute__. Dunder methods had previously worked on modules – you could, for example, use a module as a context manager simply by defining
__exit__, before those tricks broke.
Recently some historical features have made a comeback, the module
__getattr__ among them, and so the existing hack (a module replacing itself with a class in
sys.modules at import time) should be no longer necessary.
In Python 3.7+, you just use the one obvious way. To customize attribute access on a module, define a
__getattr__ function at the module level which should accept one argument (name of attribute), and return the computed value or raise an
# my_module.py def __getattr__(name: str) -> Any: ...
This will also allow hooks into “from” imports, i.e. you can return dynamically generated objects for statements such as
from my_module import whatever.
On a related note, along with the module getattr you may also define a
__dir__ function at module level to respond to
dir(my_module). See PEP 562 for details.
This question is answered By – wim
This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0