为了账号安全,请及时绑定邮箱和手机立即绑定

模块上的__getattr__

模块上的__getattr__

翻阅古今 2019-08-02 14:36:20
模块上的__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


查看完整回答
反对 回复 2019-08-02
?
守着一只汪

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__])


查看完整回答
反对 回复 2019-08-02
  • 3 回答
  • 0 关注
  • 599 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信