模块上的__getattr__如何__getattr__在模块上实现类的等价?例当调用模块静态定义的属性中不存在的函数时,我希望在该模块中创建一个类的实例,并在模块上的属性查找中使用与失败相同的名称调用其上的方法。class A(object):
def salutation(self, accusative):
print "hello", accusative# note this function is intentionally on the module, and not the class abovedef __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
3 回答
天涯尽头无女友
TA贡献1831条经验 获得超9个赞
不久之前,Guido宣称所有关于新式类的特殊方法查找都会绕过__getattr__
和__getattribute__
。Dunder方法曾经工作的模块-你可以,例如,使用一个模块作为一个上下文管理器简单地通过定义__enter__
和__exit__
,这些技巧之前爆发。
最近一些历史特征已经卷土重来,其中的模块__getattr__
,所以现在的黑客攻击(一个模块sys.modules
在导入时替换为一个类)应该不再需要了。
在Python 3.7+中,您只需使用一种显而易见的方法。要自定义模块上的属性访问权限,请__getattr__
在模块级别定义一个函数,该函数应接受一个参数(属性名称),并返回计算值或引发AttributeError
:
# my_module.pydef __getattr__(name: str) -> Any: ...
这也允许挂钩进入“from”导入,即你可以为语句返回动态生成的对象from my_module import whatever
。
在相关的说明中,与模块getattr一起,您还可以__dir__
在模块级别定义一个函数来响应dir(my_module)
。有关详细信息,请参阅PEP 562。
守着一只汪
TA贡献1872条经验 获得超3个赞
这是一个hack,但你可以用一个类包装模块:
class Wrapper(object): def __init__(self, wrapped): self.wrapped = wrapped def __getattr__(self, name): # Perform custom logic here try: return getattr(self.wrapped, name) except AttributeError: return 'default' # Some sensible defaultsys.modules[__name__] = Wrapper(sys.modules[__name__])
添加回答
举报
0/150
提交
取消