Why don't Python class method decorators receive the method as a bound method?
When I create a decorator for a class method, it always receives the method 开发者_StackOverflow中文版as of type "function".
However, when I play around with things a bit, I only get back bound methods:
class Test(object):
def save(self):
print "Save called"
def func(self):
print "Func called"
And then:
>>> type(Test.func)
<type 'instancemethod'>
>>> type(Test().func)
<type 'instancemethod'>
What I would ultimately like to do is create a class method decorator, which also decorates some other method on the same class. How would I go about doing this?
This is impossible; you'd have to use a class decorator or metaclass instead. Decorator syntax
class Foo(object):
@dec
def bar(self): pass
means
class Foo(object)
def bar(self): pass
bar = dec(bar)
where a class
definition is processed as: execute the body, then gather the definitions and wrap them in a class
object. I.e., decoration is done before the class
comes into existence.
It depens on the order of stuff that happens.
If you take a "normal" method. the following happens:
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>
Should be the same. What happens here? Well, look:
>>> f = Test.__dict__["func"]
>>> m = f.__get__(None, Test)
>>> f, m
(<function func at 0x00B43E30>, <unbound method Test.func>)
The first is the original function object, the second one the method object which is created when doing an actual method call.
Furthermore, if you have an instance:
>>> 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>>
So this happens on attribute access.
Now to your question:
The reason this happens is because the original function is present in the class's __dict__
. The method object creation happens on access.
精彩评论