在 Ruby 中,我可以将一段代码传递给一个方法。
例如,我可以将不同的代码块传递给get_schedules_with_retries方法。
并通过调用 black.call 调用块
我想知道如何在 Python 中实现该逻辑,
因为我有很多代码块,需要重试模式。
我不喜欢retry logic在许多代码块中复制粘贴
例子:
def get_schedules_with_retries(&block)
max_retry_count = 3
retry_count = 0
while (retry_count < max_retry_count)
begin
schedules = get_more_raw_schedules
block.call(schedules)
rescue Exception => e
print_error(e)
end
if schedules.count > 0
break
else
retry_count+=1
end
end
return schedules
end
get_schedules_with_retries do |schedules|
# do something here
end
get_schedules_with_retries do |schedules|
# do another thing here
end
Run Code Online (Sandbox Code Playgroud)
在 Python 中,块是一种语法特征(块开头语句(如 if 或 def)下的缩进)而不是对象。您期望的功能可能是闭包(可以访问块外部的变量),您可以使用内部函数来实现它,但可以使用任何可调用的功能。由于lambdaPython 中的工作方式,您所展示的内联函数定义do |arg|仅限于单个表达式。
这是用 Python 粗略重写的示例代码。
def get_schedules_with_retries(callable, max_retry_count = 3):
retry_count = 0
while retry_count < max_retry_count:
schedules = get_more_raw_schedules()
try:
callable(schedules)
except: # Note: could filter types, bind name etc.
traceback.print_exc()
if schedules.count > 0:
break
else:
retry_count+=1
return schedules
get_schedules_with_retries(lambda schedules: single_expression)
def more_complex_function(schedules):
pass # do another thing here
get_schedules_with_retries(more_complex_function)
Run Code Online (Sandbox Code Playgroud)
一种变体使用for循环来明确循环是有限的:
def call_with_retries(callable, args=(), tries=3):
for attempt in range(tries):
try:
result=callable(*args)
break
except:
traceback.print_exc()
continue
else: # break never reached, so function always failed
raise # Reraises the exception we printed above
return result
Run Code Online (Sandbox Code Playgroud)
通常,当传递这样的可调用对象时,您已经在某个地方拥有了您想要的函数,并且不需要重新定义它。例如,对象上的方法(绑定方法)是完全有效的可调用对象。