Why can @decorator not decorate a staticmethod or a classmethod?
Why can decorator
not decorate a staticmethod or a classmethod?
from decorator import decorator
@decorator
def print_function_name(function, *args):
print '%s was called.' % function.func_name
return function(*args)
class My_class(object):
@print_function_name
@classmethod
def get_dir(cls):
return dir(cls)
@print_function_name
@staticmethod
def get_a():
return 'a'
Both get_dir
and get_a
result in AttributeError: <'classmethod' or 'staticmethod'>, object has no attribute '__name__'
.
Why does 开发者_开发问答decorator
rely on the attribute __name__
instead of the attribute func_name
? (Afaik all functions, including classmethods and staticmethods, have the func_name
attribute.)
Edit: I'm using Python 2.6.
classmethod
and staticmethod
return descriptor objects, not functions. Most decorators are not designed to accept descriptors.
Normally, then, you must apply classmethod
and staticmethod
last when using multiple decorators. And since decorators are applied in "bottom up" order, classmethod
and staticmethod
normally should be top-most in your source.
Like this:
class My_class(object):
@classmethod
@print_function_name
def get_dir(cls):
return dir(cls)
@staticmethod
@print_function_name
def get_a():
return 'a'
It works when @classmethod
and @staticmethod
are the top-most decorators:
from decorator import decorator
@decorator
def print_function_name(function, *args):
print '%s was called.' % function.func_name
return function(*args)
class My_class(object):
@classmethod
@print_function_name
def get_dir(cls):
return dir(cls)
@staticmethod
@print_function_name
def get_a():
return 'a'
Is this what you wanted?
def print_function_name(function):
def wrapper(*args):
print('%s was called.' % function.__name__)
return function(*args)
return wrapper
class My_class(object):
@classmethod
@print_function_name
def get_dir(cls):
return dir(cls)
@staticmethod
@print_function_name
def get_a():
return 'a'
精彩评论