基本“什么都不做”装饰类:
import inspect
import functools
from copy import copy
class Deco:
def __init__(self, func):
self.__self__ = None # "__self__" is also used by bound methods
functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs):
# if bound to an object, pass it as the first argument
if self.__self__ is not None:
args = (self.__self__,) + args
#== change the following line to make the decorator do something ==
return self.__wrapped__(*args, **kwargs)
def __get__(self, instance, owner):
if instance is None:
return self
# create a bound copy
bound = copy(self)
bound.__self__ = instance
# update __doc__ and similar attributes
functools.update_wrapper(bound, self.__wrapped__)
# add the bound instance to the object's dict so that
# __get__ won't be called a 2nd time
setattr(instance, self.__wrapped__.__name__, bound)
return bound
,而另一种参数:
class DecoWithArgs:
#== change the constructor's parameters to fit your needs ==
def __init__(self, *args):
self.args = args
self.__wrapped__ = None
self.__self__ = None
def __call__(self, *args, **kwargs):
if self.__wrapped__ is None:
return self.__wrap(*args, **kwargs)
else:
return self.__call_wrapped_function(*args, **kwargs)
def __wrap(self, func):
# update __doc__ and similar attributes
functools.update_wrapper(self, func)
return self
def __call_wrapped_function(self, *args, **kwargs):
# if bound to an object, pass it as the first argument
if self.__self__ is not None:
args = (self.__self__,) + args
#== change the following line to make the decorator do something ==
return self.__wrapped__(*args, **kwargs)
def __get__(self, instance, owner):
if instance is None:
return self
# create a bound copy of this object
bound = copy(self)
bound.__self__ = instance
bound.__wrap(self.__wrapped__)
# add the bound decorator to the object's dict so that
# __get__ won't be called a 2nd time
setattr(instance, self.__wrapped__.__name__, bound)
return bound
这样的实现让我们使用的方法装饰以及功能,所以我认为这应该被认为是很好的做法。
也相关:[Python装饰最佳实践,使用类与函数](http://stackoverflow.com/questions/10294014/python-decorator-best-practice-using-a-class-vs-a-功能) –
为什么你需要它是一个类?装饰者只是一个函数有什么问题? –
@PaulRooney在我的特殊情况下(我正在编写一个GUI库),我想在函数中存储一些属性(如键盘热键,描述,类别等)以及一些函数(比如''。 start_in_new_thread()','.update_status()')。不是强制所有这些属性到函数上,而是编写一个包装类并完全替换该函数。 –