如何__getattr__在模块上的类上实现等价于a的等价物?
__getattr__
当调用模块的静态定义属性中不存在的函数时,我希望在该模块中创建一个类的实例,并使用与该模块上的属性查找失败相同的名称调用该方法。
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
不久前,Guido宣布对新型类的所有特殊方法查找都绕过__getattr__and__getattribute__。Dunder方法曾经工作的模块- 你可以,例如,使用一个模块作为一个上下文管理器简单地通过定义__enter__和__exit__,这些技巧之前爆发。
__getattribute__
__enter__
__exit__
最近,一些历史功能已经卷土重来,其中的一个模块已被卷土重来,__getattr__因此,sys.modules不再需要现有的hack(在导入时将一个模块替换为一个类)。
sys.modules
在Python 3.7+中,您仅使用一种显而易见的方法。要自定义模块上的属性访问,请__getattr__在模块级别定义一个函数,该函数应接受一个参数(属性名称),然后返回计算值或引发一个AttributeError:
AttributeError
# my_module.py def __getattr__(name: str) -> Any: ...
这也将允许钩入“ from”导入,即,您可以为诸如的语句返回动态生成的对象from my_module import whatever。
from my_module import whatever
与此相关的是,您还可以与模块getattr一起__dir__在模块级别定义一个函数以响应dir(my_module)。有关详细信息,请参见PEP 562。
__dir__
dir(my_module)