如何在类、模块上实现 __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
原文由 Matt Joiner 发布,翻译遵循 CC BY-SA 4.0 许可协议
不久前,Guido 宣布所有对新型类的特殊方法查找绕过
__getattr__
和__getattribute__
。 Dunder 方法以前适用于模块——例如,在这些技巧失效之前,您可以简单地通过定义__enter__
和__exit__
将 模块用作上下文管理器。最近一些历史特征卷土重来,模块
__getattr__
其中,因此现有的 hack(一个模块在导入时用sys.modules
中的类替换自身)应该不再必要的。在 Python 3.7+ 中,您只需使用一种显而易见的方法。要自定义模块上的属性访问,请在模块级别定义一个
__getattr__
函数,该函数应接受一个参数(属性名称),并返回计算值或引发AttributeError
:这也将允许挂钩到“来自”导入,即您可以为语句返回动态生成的对象,例如
from my_module import whatever
。在相关说明中,除了模块 getattr 之外,您还可以在模块级别定义
__dir__
函数以响应dir(my_module)
。有关详细信息,请参阅 PEP 562 。