多个出口是否可行以简化长的Python函数?

4 投票
2 回答
1378 浏览
提问于 2025-04-17 18:02

我有一个很长的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

一个问题是,这个函数里的ifelse部分都有很多代码,可能会超过一个屏幕的长度。这样一来,我们很容易就会搞混缩进,或者需要不停地向上滚动才能看到当前的条件是什么。

为了改善这个问题,一个想法是把它拆分成几个小函数:

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"

不过,有些编码风格不建议使用多个退出点,特别是当它们相隔很远的时候。

所以问题是:有没有什么更好的、符合Python风格的方法来让原来的代码结构更易读和更好维护呢?

2 个回答

2

黄金法则是:一个函数可以有多个返回点,但只要这样做能让代码更易读,如果你的代码量很大,我担心返回值和把值复制到一个变量再返回其实没有什么区别。

我觉得你的问题更多是关于设计、抽象层次和你这个函数的语义。

以下问题可能会帮助你:

  • 这个函数的功能是否很集中?也就是说,它只做一件事。比如,不要让它既计算收入,又打印收入,还把收入发送到服务器,最后还带着狗去散步。

  • 这个函数的参数超过7个吗?如果是的话,说明你的函数抽象层次可能不太合适。

如果你能提供更多关于你这个函数的信息(它做什么,返回什么,参数是什么),那会更有帮助。也许你更适合用两个类来处理这个问题……

不过,作为一般性的建议,我会说你最好分析一下每个具体的操作,把它们拆分成小的、功能明确的函数,然后让你的主函数按顺序调用这些小函数,而不是让它自己完成所有工作。而且,只有两个函数来处理真和假的情况的做法可能是错误的,因为这可能导致你在两个函数中写了相似的代码(对于真和假),这样就重复了。

5

在一个函数里有多个退出点是完全可以的,要求只有一个退出点的说法是个老规矩,源于早期编程语言没有异常处理的时代,那时候为了集中处理错误,只有一个退出点是比较合理的。但现在有了异常处理,这个老规矩就不再适用了。

有些情况下,多个退出点反而更合适,即使在坚持单一退出点的原则下,比如在函数开头使用的保护性语句,当参数不合适或者函数的大部分内容明显不合适时,需要快速返回。在这种情况下,提前退出是很有意义的,因为这样可以避免在函数里写很多复杂的if语句,减少代码的缩进层级。

为了更全面,这里有一个解释,进一步阐述我的观点。

撰写回答