4

我有一个很长的那个结构的 Python 函数:

def the_function(lots, of, arguments):

    return_value = None

    if some_important_condition:

        # a lot of stuff here

        return_value = "some value"

    else:

        # even more stuff here

        return_value = "some other value"

    return return_value

一个问题是 theifelseblock 都包含不止一屏的代码。很容易忘记缩进,或者不得不向上滚动查看我们目前处于什么状态。

改进这一点的一个想法是将其拆分为几个功能:

def case_true(lots, of, arguments):

    # a lot of stuff here

    return "some value"

def case_false(lots, of, arguments):

    # even more stuff here

    return "some other value"

def the_function(lots, of, arguments):

    return_value = None

    if some_important_condition:

        return_value = case_true(lots, of, arguments)

    else:

        return_value = case_false(lots, of, arguments)

    return return_value

但考虑到争论的杂耍,我不确定这是否能解决问题。

另一个想法是使用多个退出点:

def the_function(lots, of, arguments):

    if some_important_condition:

        # a lot of stuff here

        return "some value"

    # even more stuff here

    return "some other value"

但是有几种编码风格建议不要使用多个退出点,尤其是当它们隔着屏幕时。

问题是:使原始结构更具可读性和可维护性的首选pythonic方法是什么?

4

2 回答 2

5

在一个函数中有多个出口点是非常好的,只有一个出口点的要求是一个古老的约定,可以追溯到编程语言没有异常处理的时代,只有一个出口点是有意义的集中错误处理。例外的存在使旧的约定过时了。

在某些情况下,即使在执行单个函数退出点策略时,也可以选择多个退出点 - 例如,函数顶部的保护子句需要从函数快速返回“如果参数错误,或者大部分函数显然是不合适的”,在这种情况下,“在完成任何有意义的工作之前从顶部退出是很有意义的。否则,您将需要覆盖大部分函数的大量 if 语句,给出你又是另一个级别的缩进”。

为了完整起见,这里有一个扩展我的观点的解释。

于 2013-03-05T17:27:56.120 回答
2

黄金法则是:一个函数可以有多个返回点,但只要提高可读性,如果你的代码如此庞大,返回和复制到一个变量中恐怕没有任何区别回来。

我认为您的问题更多是关于您的例程的设计、抽象级别和语义。

这些问题可能会对您有所帮助:

  • 例程是否具有功能凝聚力?即:它只做一件事。不像计算收入,打印它们,将它们发送到服务器并与狗一起散步。

  • 该函数是否有超过 7 个参数?如果是这样,很可能您的例程的抽象级别不合适。

如果你发布更多关于你的例程细节的信息(它做什么,它返回什么,什么参数),这将会有所帮助。这可能是你最好使用两个类......

但是,作为一般性答案,我会说您最好分析各个操作,将它们分解为具有良好内聚力的小函数,然后将您的函数变成这些小函数的顺序调用者,而不是让它完成工作。并且只有 case_true 和 case_false 两个函数的方法可能是错误的,因为很可能您在两个函数中都有相似的操作(对于 true 和 false)并且您对它们进行了两次编码。

于 2013-03-05T18:40:07.697 回答