尽管我喜欢将自己视为一个相当称职的Python编码器,但我从来没能理解过的语言的一方面是装饰器。
我知道它们是什么(表面上),我已经阅读了有关堆栈溢出的教程,示例和问题,而且我了解语法,可以编写自己的语法,偶尔使用@classmethod和@staticmethod,但是使用装饰器来解决我自己的Python代码中的问题。 我从来没有遇到过这样的问题,我想:“嗯……这看起来像是装饰工的工作!”
因此,我想知道你们是否可以提供一些示例,说明您在自己的程序中使用装饰器的位置,并希望我会收到一个“哈!” 片刻, 让他们。
#1楼
我用这个装饰器来修复参数
def fill_it(arg):
if isinstance(arg, int):
return "wan" + str(arg)
else:
try:
# number present as string
if str(int(arg)) == arg:
return "wan" + arg
else:
# This should never happened
raise Exception("I dont know this " + arg)
print "What arg?"
except ValueError, e:
return arg
def fill_wanname(func):
def wrapper(arg):
filled = fill_it(arg)
return func(filled)
return wrapper
@fill_wanname
def get_iface_of(wanname):
global __iface_config__
return __iface_config__[wanname]['iface']
在重构某些函数需要传递参数“ wanN”时编写的代码,但是在我的旧代码中,我仅传递了N或'N'
#2楼
装饰器可用于轻松创建函数方法变量。
def static_var(varname, value):
'''
Decorator to create a static variable for the specified function
@param varname: static variable name
@param value: initial value for the variable
'''
def decorate(func):
setattr(func, varname, value)
return func
return decorate
@static_var("count", 0)
def mainCallCount():
mainCallCount.count += 1
#3楼
我正在使用以下装饰器来使函数成为线程安全的。 它使代码更具可读性。 它几乎与John Fouhy提出的类似,但是区别在于,一个函数可以处理单个函数,因此无需显式创建锁对象。
def threadsafe_function(fn):
"""decorator making sure that the decorated function is thread safe"""
lock = threading.Lock()
def new(*args, **kwargs):
lock.acquire()
try:
r = fn(*args, **kwargs)
except Exception as e:
raise e
finally:
lock.release()
return r
return new
class X:
var = 0
@threadsafe_function
def inc_var(self):
X.var += 1
return X.var
#4楼
当然,一种明显的用途是用于日志记录:
import functools
def log(logger, level='info'):
def log_decorator(fn):
@functools.wraps(fn)
def wrapper(*a, **kwa):
getattr(logger, level)(fn.__name__)
return fn(*a, **kwa)
return wrapper
return log_decorator
# later that day ...
@log(logging.getLogger('main'), level='warning')
def potentially_dangerous_function(times):
for _ in xrange(times): rockets.get_rocket(NUCLEAR=True).fire()
#5楼
我主要将它们用于调试(包装打印其参数和结果的函数)和验证(例如,检查参数是否为正确类型,或者对于Web应用程序,用户是否具有足够的特权来调用特定参数)方法)。