我是python的新手,我正在编写使用OAuth进行身份验证的代码,当令牌在60分钟后过期时,它需要获得一个新的。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="rad[timeout > 30]">
<xsl:copy>
<timeout>100</timeout>
</xsl:copy>
<warnings>
<warning>Time out of RAD changed.</warning>
</warnings>
</xsl:template>
</xsl:stylesheet>
我目前有这个代码来处理一个新的令牌,如果它到期,但问题是,如果有一个异常,它会跳过它需要做的动作。我知道我可以把try块里面的内容添加到try:
if uploadedContent is not None:
thing.action(uploadedContent)
except LoginOrScopeRequired:
print("Logging in...")
set_access_credentials({"identity", "submit"}, get_access_token())
块的末尾,但它有更优雅的方法吗?
我的一些研究导致了except
声明,但我不太了解with
,知道它是否能解决我的问题。那么将它追加到最终的最佳解决方案还是有更好的解决方案?
答案 0 :(得分:3)
某些语言(如ruby
)允许您在异常catch块中放置retry
语句,这使得这非常简单。不幸的是,在Python中,您需要将其包装在while
语句中:
success = False
while not success
try:
if uploadedContent is not None:
thing.action(uploadedContent)
success = True
except LoginOrScopeRequired:
print("Logging in...")
set_access_credentials({"identity", "submit"}, get_access_token())
请注意,只有在没有异常发生时才会到达success = True
行。
修改强>
您还需要跟踪计数器中attempts
的数量,以确保它不会永远循环,并在3次重试后退出。
答案 1 :(得分:3)
使用函数装饰器/包装器来执行此操作被认为是惯用的Python:
示例:强>
#!/usr/bin/env python
from functools import wraps
def retry_on_error(ntries=1):
"""
A decorator that returns a wrapper function that calls
the wrapped function repeatedly up to ntries if an
exception is encountered.
"""
def decorator(f): # wrapping the original function
@wraps(f) # make the wrapped function look like the original
def wrapper(*args, **kwargs): # our function wrapped that calls the original
for i in xrange(ntries):
try:
return f(*args, **kwargs)
except Exception as e:
print("Error executing {0:s} retrying {1:d}/{2:d}".format(f.__name__, i, ntries))
print("Error was {0:s}".format(e))
return wrapper
return decorator # returning the new wrapped function
@retry_on_error()
def f():
n = getattr(f, "n", 0)
try:
if not n:
raise ValueError("n < 0")
finally:
setattr(f, "n", n + 1)
<强>输出:强>
$ python -i foo.py
>>> f()
Error executing f retrying 0/1
Error was n < 0
>>> f()
>>>
有关其他示例,请参阅:Python Decorators。
更新还有一个很好的库,可以通过更多功能实现此功能:retrying以及其他一些相关/类似问题How to retry after exception in python?和{{ 3}}
更新#2:我已经对装饰师进行了一些评论,所以希望您能够了解过程中每个步骤的进展情况。不可否认,装饰师一开始并不容易理解,所以我建议你阅读Pythonic way of retry running a function