虽然我喜欢认为自己是一个相当称职的Python程序员,但我始终无法理解该语言的一个方面是装饰器。
我知道它们是什么(表面上),我读过教程,例子,关于Stack Overflow的问题,我理解语法,可以自己写,偶尔使用@classmethod和@staticmethod,但我从来没有想过在我自己的Python代码中使用装饰器来解决问题。我从来没有遇到过这样的问题:“嗯……这看起来像是装修师的工作!”
所以,我想知道你们是否可以提供一些在你们自己的程序中使用装饰器的例子,希望我能有一个“啊哈!”的时刻,并得到它们。
我使用装饰器进行类型检查参数,这些参数通过一些RMI传递给我的Python方法。因此,与其重复相同的参数计数,一遍又一遍地抛出异常。
例如,不要:
def myMethod(ID, name):
if not (myIsType(ID, 'uint') and myIsType(name, 'utf8string')):
raise BlaBlaException() ...
我只是声明:
@accepts(uint, utf8string)
def myMethod(ID, name):
...
并且接受()为我做了所有的工作。
对于nosetests,你可以编写一个装饰器,它提供一个带有几组参数的单元测试函数或方法:
@parameters(
(2, 4, 6),
(5, 6, 11),
)
def test_add(a, b, expected):
assert a + b == expected
我使用它们进行同步。
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
lock.acquire()
try:
return f(*args, **kw)
finally:
lock.release()
return newFunction
return wrap
正如评论中指出的,从Python 2.5开始,可以将with语句与线程结合使用。锁(或多处理)。Lock自2.6版起)对象来简化decorator的实现:
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
with lock:
return f(*args, **kw)
return newFunction
return wrap
不管怎样,你可以这样使用它:
import threading
lock = threading.Lock()
@synchronized(lock)
def do_something():
# etc
@synchronzied(lock)
def do_something_else():
# etc
基本上,它只是把lock.acquire() / lock.release()放在函数调用的两边。