python回调与控制流中的异常

时间:2016-08-18 10:37:15

标签: python callback control-flow

什么是控制流,回调或异常的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的?

1 个答案:

答案 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函数不仅可以进行验证,还可以处理错误处理,并在您的示例中执行用户登录。