什么是控制流,回调或异常的python?例如,如果我写了一个用户登录逻辑,我可以用这种方式编写它:
例外
try:
valid_data = validate(form)
try:
do_login(valid_data)
return SuccessLoginTemplate()
except LoginError:
return RenderTemplate(form)
except FormError:
return RenderTemplate(form)
回调:
validate(form, on_form_ok, on_form_error)
def on_form_ok(valid_data):
do_login(valid_data, on_login_success, on_login_error)
def on_form_error(errors):
return RenderTemplate(form)
def on_login_success(user):
return SuccessLoginTemplate()
def on_login_error(errors):
return RenderTemplate(form)
看起来大多数python代码都是通过Exceptions在1例中编写的,但IMO 回调风格在DSL视图中更具表现力。在案例2中,没有中间代码“从一个电话到另一个电话预先换货的线索”我的意思是:
try:
valid_data = validate(form)
try:
#mess with some intermediate vars
do_login(valid_data)
#mess with some intermediate vars
return SuccessLoginTemplate()
except LoginError:
#mess with some intermediate vars
return RenderTemplate(form)
except FormError:
#mess with some intermediate vars
return RenderTemplate(form)
IMO这个混乱的中间变量降低了代码的可读性,因为在回调的情况下,中间代码进入回调,它更容易理解它然后它包含在函数中,所以它得到一些上下文(我的意思是函数名称,携带一些DSL语义)并且在异常情况下,此代码从任何上下文中解除绑定,因此更难阅读)
此外,我不想检查功能的结果 - 这也使一些中间变量混乱。我寻找更清晰的方式将计算链接在更多功能风格中,如monad或CPS风格。因此,IMO回调是更具表现力的方式,但它是如何pythonic的?
答案 0 :(得分:0)
IMO,你有3个明显的背景:1 try
和2个不同的except
s所有变量和东西被明确地操纵和传递,而你不知道回调(除非你写文档或这样的任何事情)表达至少你传递的回调的参数是什么。具有异常名称的异常块为代码块提供了足够的含义。
你甚至必须像这样实现validate
(带回调)
def validate(data, on_success, on_error1, on_error2):
try:
# do_validation_stuff here
except Exception1:
on_error1()
except Exception2:
on_error2()
else:
on_success()
因此validate
函数不仅可以进行验证,还可以处理错误处理,并在您的示例中执行用户登录。