猿问

模块上的__getattr__

模块上的__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


翻阅古今
浏览 600回答 3
3回答

天涯尽头无女友

不久之前,Guido宣称所有关于新式类的特殊方法查找都会绕过__getattr__和__getattribute__。Dunder方法曾经工作的模块-你可以,例如,使用一个模块作为一个上下文管理器简单地通过定义__enter__和__exit__,这些技巧之前爆发。最近一些历史特征已经卷土重来,其中的模块__getattr__,所以现在的黑客攻击(一个模块sys.modules在导入时替换为一个类)应该不再需要了。在Python 3.7+中,您只需使用一种显而易见的方法。要自定义模块上的属性访问权限,请__getattr__在模块级别定义一个函数,该函数应接受一个参数(属性名称),并返回计算值或引发AttributeError:#&nbsp;my_module.pydef&nbsp;__getattr__(name:&nbsp;str)&nbsp;->&nbsp;Any: &nbsp;&nbsp;&nbsp;&nbsp;...这也允许挂钩进入“from”导入,即你可以为语句返回动态生成的对象from my_module import whatever。在相关的说明中,与模块getattr一起,您还可以__dir__在模块级别定义一个函数来响应dir(my_module)。有关详细信息,请参阅PEP 562。

守着一只汪

这是一个hack,但你可以用一个类包装模块:class&nbsp;Wrapper(object): &nbsp;&nbsp;def&nbsp;__init__(self,&nbsp;wrapped): &nbsp;&nbsp;&nbsp;&nbsp;self.wrapped&nbsp;=&nbsp;wrapped&nbsp;&nbsp;def&nbsp;__getattr__(self,&nbsp;name): &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Perform&nbsp;custom&nbsp;logic&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;try: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;getattr(self.wrapped,&nbsp;name) &nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;AttributeError: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;'default'&nbsp;#&nbsp;Some&nbsp;sensible&nbsp;defaultsys.modules[__name__]&nbsp;=&nbsp;Wrapper(sys.modules[__name__])
随时随地看视频慕课网APP

相关分类

Python
我要回答