我如何很好地編寫裝飾器?好的Python裝飾器
特別問題包括:與其他裝飾的兼容性,簽名的保護,等等
我想避免的裝飾模塊的依賴如果有可能,但如果有足夠的優勢的話,我會考慮。
相關
- Preserving signatures of decorated functions - 更具體的問題。這裏的答案是用@ decorator.decorator使用註釋裝飾器的第三方裝飾模塊
我如何很好地編寫裝飾器?好的Python裝飾器
特別問題包括:與其他裝飾的兼容性,簽名的保護,等等
我想避免的裝飾模塊的依賴如果有可能,但如果有足夠的優勢的話,我會考慮。
相關
寫一個好的裝飾器是沒有什麼不同,然後寫一個很好的功能。這意味着,理想情況下,使用docstrings並確保裝飾器包含在您的測試框架中。
您應該在標準庫(自2.5開始)中使用decorator
庫或更好的functools.wraps()
修飾器。
除此之外,最好讓你的裝飾者集中精力和精心設計。如果您的裝飾器需要特定參數,請勿使用*args
或**kw
。而做填寫你所期望的參數,所以代替:
def keep_none(func):
def _exec(*args, **kw):
return None if args[0] is None else func(*args, **kw)
return _exec
...使用... ...
def keep_none(func):
"""Wraps a function which expects a value as the first argument, and
ensures the function won't get called with *None*. If it is, this
will return *None*.
>>> def f(x):
... return x + 5
>>> f(1)
6
>>> f(None) is None
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
>>> f = keep_none(f)
>>> f(1)
6
>>> f(None) is None
True"""
@wraps(func)
def _exec(value, *args, **kw):
return None if value is None else func(value, *args, **kw)
return _exec
使用functools來保存名稱和文檔。簽名將不會被保留。
直接從doc。
>>> from functools import wraps
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwds):
... print 'Calling decorated function'
... return f(*args, **kwds)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
... print 'Called example function'
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'
其良好ettiquete使維基回答自己的問題。 – voyager 2009-09-11 14:42:43
確實有道理 – Casebash 2009-09-11 23:34:30