为什么Python类方法装饰器不接收方法作为绑定方法?

时间:2011-09-20 11:40:45

标签: python

当我为类方法创建装饰器时,它总是接收类型为“function”的方法。

但是,当我稍微讨论一下时,我只能回到绑定方法:

class Test(object):
    def save(self):
        print "Save called"
    def func(self):
        print "Func called"

然后:

>>> type(Test.func)
<type 'instancemethod'>
>>> type(Test().func)
<type 'instancemethod'>

我最终想要做的是创建一个类方法装饰器,它也在同一个类上装饰一些其他方法。我该怎么做呢?

2 个答案:

答案 0 :(得分:3)

这是不可能的;你必须使用类装饰器或元类。装饰器语法

class Foo(object):
    @dec
    def bar(self): pass

装置

class Foo(object)
    def bar(self): pass
    bar = dec(bar)

其中class定义被处理为:执行主体,然后收集定义并将它们包装在class对象中。即,装饰在 class出现之前完成。

答案 1 :(得分:2)

它取决于发生的事情的顺序。

如果采取“正常”方法。发生以下情况:

class Test(object):
    def save(self):
        print "Save called"
    def func(self):
        print "Func called"

>>> Test.__dict__["func"]
<function func at 0x00B43E30>
>>> Test.func
<unbound method Test.func>

应该是一样的。这里发生了什么?嗯,看:

>>> f = Test.__dict__["func"]
>>> m = f.__get__(None, Test)
>>> f, m
(<function func at 0x00B43E30>, <unbound method Test.func>)

第一个是原始函数对象,第二个是在进行实际方法调用时创建的方法对象。

此外,如果你有一个实例:

>>> t = Test()
>>> t.func
<bound method Test.func of <__main__.Test object at 0x00B48AB0>>
>>> f.__get__(t, Test)
<bound method Test.func of <__main__.Test object at 0x00B48AB0>>

所以这会发生在属性访问上。

现在回答你的问题:

发生这种情况的原因是因为原始函数存在于类__dict__中。方法对象创建在访问时发生。