基本「什麼都不做」裝飾類:
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()')。不是強制所有這些屬性到函數上,而是編寫一個包裝類並完全替換該函數。 –