Is it possible to determine which class a function is a method of?
For example, if I'm decorating a met开发者_StackOverflow社区hod like so
def my_decorator(fn):
# Do something based on the class that fn is a method of
def decorated_fn(*args, **kwargs):
fn(*args, **kwargs)
return decorated_fn
class MyClass(object):
@my_decorator
def my_method(self, param):
print "foo"
Is it possible in my_decorator to determine where fn came from?
Short answer: No.
Longer answer: You can do it by mucking about in the stack trace (see the inspect
module) but it's not a great idea.
Full answer: At the time the function gets decorated, it's still an unbound function. Try the following:
def my_dec(fn):
print dir(fn) # Has "func_code" and "func_name"
return fn
class A(object):
@my_dec
def test(self):
pass
print dir(A.test) # Has "im_class" and "im_self"
You can see that the raw function gets passed to the decorator, while the bound function is available after the class is declared.
The way to accomplish this is to just the function decorator in conjunction with either a metaclass or a class decorator. In either case, the function decorator can set a flag on the function, and the metaclass or class decorator can look for it and do the appropriate thing.
No. You'll have to defer it until decorated_fn()
is called.
精彩评论