<p>从函数属性获取重试次数,而不是参数。你知道吗</p>
<pre><code>def tryagain(func):
def retrier(*args,**kwargs):
retries = getattr(func, "attempts", MAXIMUM)
while retries + 1 > 0:
try:
return func(*args, **kwargs)
except Exception as e:
logging.error("Failed. Trying again")
last_exception = e
retries -= 1
else:
logging.error("Tried %d times and failed, giving up", retries)
raise last_exception
return retrier
@tryagain
def my_func(...):
...
my_func.attempts = 10
my_func() # Will try it 10 times
</code></pre>
<p>要使<code>MAXIMUM</code>成为调用函数时可以指定的内容,请将定义更改为</p>
<pre><code>def tryagain(maximum=10):
def _(f):
def retrier(*args, **kwargs):
retries = getattr(func, "attempts", maximum)
while retries + 1 > 0:
try:
return func(*args, **kwargs)
except Exception as e:
logging.error("Failed. Trying again")
last_exception = e
retries -= 1
else:
logging.error("Tried %d times and failed, giving up", retries)
raise last_exception
return retrier
return _
</code></pre>
<p>尽管仍然存在与<code>attempts</code>属性发生名称冲突的风险,但是函数属性很少被使用这一事实使得将<code>tryagain</code>文档化为不使用具有预先存在的<code>attempts</code>属性的函数更为合理。你知道吗</p>
<p>(我把它作为一个练习来修改<code>tryagain</code>以获取一个属性名作为参数:</p>
<pre><code>@tryagain(15, 'max_retries')
def my_func(...):
...
</code></pre>
<p>以便您可以在装修时选择一个未使用的名称。因此,还可以使用<code>tryagain</code>的参数作为要添加到<code>my_func</code>的关键字参数的名称。)</p>