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

如何在新样式类中拦截对python“魔法”方法的调用?

如何在新样式类中拦截对python“魔法”方法的调用?

qq_遁去的一_1 2019-08-19 15:01:05
如何在新样式类中拦截对python“魔法”方法的调用?我试图在新的样式类中拦截对python的双下划线魔术方法的调用。这是一个简单的例子,但它显示了意图:class ShowMeList(object):     def __init__(self, it):         self._data = list(it)     def __getattr__(self, name):         attr = object.__getattribute__(self._data, name)         if callable(attr):             def wrapper(*a, **kw):                 print "before the call"                 result = attr(*a, **kw)                 print "after the call"                 return result            return wrapper        return attr如果我在列表周围使用该代理对象,我会获得非魔术方法的预期行为,但我的包装函数永远不会被魔术方法调用。>>> l = ShowMeList(range(8))>>> l #call to __repr__<__main__.ShowMeList object at 0x9640eac>>>> l.append(9)before the call after the call>> len(l._data)9如果我不从对象继承(第一行class ShowMeList:),一切都按预期工作:>>> l = ShowMeList(range(8))>>> l #call to __repr__before the call after the call[0, 1, 2, 3, 4, 5, 6, 7]>>> l.append(9)before the call after the call>> len(l._data)9如何使用新样式类完成此拦截?
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

使用__getattr____getattribute__是类的最后一个资源来响应获取属性。

考虑以下:

>>> class C:
    x = 1
    def __init__(self):
        self.y = 2
    def __getattr__(self, attr):
        print(attr)>>> c = C()>>> c.x1>>> c.y2>>> c.z
z

__getattr__只有在没有其他工作时才会调用该方法。

在您的示例中,__repr__已经在object类中定义了许多其他魔术方法 。

有一件事可以做,思考,然后定义那些魔术方法然后调用__getattr__方法。我和它的答案检查这个问题以查看一些代码。


查看完整回答
反对 回复 2019-08-19
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

对于__getattr __,newstyle vs oldstyle类的非对称行为的答案(另请参阅Python文档),修改对“魔术”方法的访问,__getattr__或者__getattribute__使用新式类不可能。这种限制使得解释器更快。


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

添加回答

举报

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