2011-09-20 57 views
1

当我为类方法创建装饰器时,它总是接收类型为“function”的方法。为什么Python类方法装饰器不能将该方法作为绑定方法接收?

然而,当我玩的东西了一下,我只拿回绑定方法:

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'> 

我最终会做的是创建一个类方法装饰器,它也在同一个类上装饰了一些其他方法。我会如何去做这件事?

+1

'Test.func'不是一个绑定的方法。 –

回答

3

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

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

装置

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

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

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__。方法对象的创建发生在访问上。