嵌套的 ‘if else’ 函数

huangapple go评论64阅读模式
英文:

Nested 'if else' functions

问题

以下是翻译好的部分:

让我们假设我们需要下载一个文件,检查一个值是否为True,如果是的话,我们需要通过电子邮件通知管理员。

我想把所有不同的任务分成易于管理的步骤(函数)。然后逐个调用每个函数。

这创建了以下函数:

def alert_admin():
    if download_file() == True: # 文件已下载,检查文件是否存在
        if extract_file() == True: # 压缩文件包含正确的文件
            if read_file() == True: # 读取文件并检查值是否存在
                if value_in_file() == True:
                    # 发送管理员电子邮件
                    pass
                else:
                    pass
            else:
                pass
        else:
            pass
    else:
        pass

这个方法感觉不太对,有没有更好的方法(更符合Python风格)来检查某些函数的结果并继续下一个步骤?

英文:

Let's say we have to download a file, check if a value is True and if so, we need to alert the admin by email.

I would like to split up all the different things to do in easy to manage steps (functions). And then call each function one by one.

This create the following function:

def alert_admin():
    if download_file() == True: # File is downloaded, check if file is present
        if extract_file() == True: # Zip file contains the correct file
            if read_file() == True: # Read the file and the value is there
                if value_in_file() == True:
                    # send the admin an email
                    pass
                else:
                    pass
            else:
                pass
        else:
            pass
    else:
        pass

This just doesn't feel right, is there a better way (a more pythonic) to check the outcome of certain functions and proceed to the next?

答案1

得分: 9

以下是翻译好的部分:

第一种方法:早期返回模式
你有几种避免深度嵌套控制流的选择。一个常见的方法是"早期返回模式" - 简单地测试下一步是否失败,如果失败就立即返回:

def alert_admin():
    if not download_file():
        return
    if not extract_file():
        return
    if not read_file():
        return
    if not value_in_file():
        return

    # 在这里发送电子邮件

第二种方法:短路评估
另一种选择是短路评估。你可以使用and布尔运算符连接函数调用 - 如果左操作数返回false,运算符将跳过评估右操作数,从而确保"早期返回":

def alert_admin():
    if download_file() and extract_file() and read_file() and value_in_file():
        # 在这里发送电子邮件

第三种方法:使用列表迭代
最后,由于所有函数调用具有相同的签名,你还可以将"步骤"存储在一个列表中并对其进行迭代 - 这可能会使维护更容易,因为你只需向列表中添加或删除函数名称以更新行为:

def alert_admin():
    required_steps = [
        download_file,
        extract_file,
        read_file,
        value_in_file
    ]

    for step in required_steps:
        if not step():
            return

    # 在这里发送电子邮件
英文:

You have a couple of options for avoiding deeply nested control flows. A popular approach is the "return early pattern" - simply test whether the next step fails, then return immediately if it does:

def alert_admin():
    if not download_file():
        return
    if not extract_file():
        return
    if not read_file():
        return
    if not value_in_file():
        return

    # send email here

Another option is short-circuiting. You chain the function calls with the and boolean operator - if the left-hand operand returns false the operator will skip evaluating the right-hand operand, thus ensuring "early return" as well:

def alert_admin():
    if download_file() and extract_file() and read_file() and value_in_file():
        # send email here

Finally, since the function calls all have the same signature, you can also store the "steps" in a list and iterate over that - this might make maintenance easier as you can simply add or remove function names to/from the list to update the behavior:

def alert_admin():
    required_steps = [
        download_file
        extract_file
        read_file
        value_in_file
    ]

    for step in required_steps:
        if not step():
            return

    # send email here

huangapple
  • 本文由 发表于 2023年7月6日 18:52:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定