In Python, objects can have dynamic attributes that are not defined in their class definition. This dynamic behavior is achieved through the getattr method, which is called when an attribute lookup fails on an object. Unfortunately, modules do not inherently support __getattr__.
The goal is to mimic getattr functionality on a module such that when an attribute is not found, an instance of a predefined class is created with the same name and the method with that name is invoked on that instance.
An attempt was made to implement getattr on a module as follows:
<code class="python">class A(object): def salutation(self, accusative): print "hello", accusative # intentionally on the module, not the class def __getattr__(mod, name): return getattr(A(), name) if __name__ == "__main__": salutation("world") # hoping for __getattr__ to be invoked</code>
However, this approach encounters two obstacles:
Wrapper Method:
The sys.modules dictionary is flexible and allows for the creation of a wrapper that intercepts module access. However, this only supports accessing methods through the module, not within the module itself. Moreover, creating a new instance each time can lead to differing behavior compared to the globals approach.
Class Replacement:
As recommended by Guido van Rossum, a hackish approach involves creating a class and replacing sys.modules[__name__] with an instance of that class. This enables the use of __getattr__/__setattr__/__getattribute__. However, it comes with caveats:
While Python modules do not natively support __getattr__, the suggested solutions provide workarounds to achieve similar dynamic attribute resolution for modules.
The above is the detailed content of How to Implement getattr Functionality for Modules in Python?. For more information, please follow other related articles on the PHP Chinese website!