猿问

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

如何在新样式类中拦截对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

如何使用新样式类完成此拦截?


qq_遁去的一_1
浏览 539回答 3
3回答

蛊毒传说

使用__getattr__和__getattribute__是类的最后一个资源来响应获取属性。考虑以下:>>>&nbsp;class&nbsp;C: &nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__init__(self): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y&nbsp;=&nbsp;2 &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__getattr__(self,&nbsp;attr): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(attr)>>>&nbsp;c&nbsp;=&nbsp;C()>>>&nbsp;c.x1>>>&nbsp;c.y2>>>&nbsp;c.z z__getattr__只有在没有其他工作时才会调用该方法。在您的示例中,__repr__已经在object类中定义了许多其他魔术方法&nbsp;。有一件事可以做,思考,然后定义那些魔术方法然后调用__getattr__方法。我和它的答案检查这个问题以查看一些代码。

汪汪一只猫

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

相关分类

Python
我要回答