<p>使用具有默认值的关键字参数(如kquinn所建议的)是一个好主意,但需要包含括号:</p>
<pre><code>@redirect_output()
def foo():
...
</code></pre>
<p>如果您想要一个在装饰器上没有括号的版本,那么您必须在装饰器代码中考虑这两种情况。</p>
<p>如果使用的是Python3.0,则可以使用仅关键字参数:</p>
<pre><code>def redirect_output(fn=None,*,destination=None):
destination = sys.stderr if destination is None else destination
def wrapper(*args, **kwargs):
... # your code here
if fn is None:
def decorator(fn):
return functools.update_wrapper(wrapper, fn)
return decorator
else:
return functools.update_wrapper(wrapper, fn)
</code></pre>
<p>在Python2.x中,这可以用varargs技巧模拟:</p>
<pre><code>def redirected_output(*fn,**options):
destination = options.pop('destination', sys.stderr)
if options:
raise TypeError("unsupported keyword arguments: %s" %
",".join(options.keys()))
def wrapper(*args, **kwargs):
... # your code here
if fn:
return functools.update_wrapper(wrapper, fn[0])
else:
def decorator(fn):
return functools.update_wrapper(wrapper, fn)
return decorator
</code></pre>
<p>这些版本中的任何一个都允许您编写如下代码:</p>
<pre><code>@redirected_output
def foo():
...
@redirected_output(destination="somewhere.log")
def bar():
...
</code></pre>