4

我正在学习 Python,并试图找出构建代码的最佳方法。

假设我有一个很长的函数,并且想把它分解成更小的函数。在C中,我会将其设为顶层的“静态”函数(因为这是唯一的函数级别)。我也可能会转发声明它并将其放在使用它的现在缩短的函数之后。

现在为 Python。在 Python 中,我可以选择创建嵌套函数。由于这个新的“内部”函数实际上只是为了便于阅读而中断的较大函数的一部分,并且仅供它使用,听起来它应该是一个嵌套函数,但是将这个函数放在父函数内部会导致整个函数仍然很长,因为实际上没有代码被移出!特别是由于函数在调用之前必须完全编码,这意味着实际的短函数一直在这个伪长函数的末尾,这使得可读性很差!

对于这种情况,什么被认为是好的做法?

4

4 回答 4

2

将较小的函数放在自己的文件中并将其导入主函数中怎么样?你会有类似的东西:

def main_func():
    from impl import a, b, c

    a()
    b()
    c()

我认为这种方法具有很高的可读性:您可以看到较小的函数来自哪里,以防您想要查看它们,导入它们是单行的,并且主要函数的实现是直接可见的。通过选择适当的文件名/位置,您还可以告诉用户这些函数不打算在外部使用main_func(无论如何,您没有隐藏在 Python 中的真实信息)。

顺便说一句:这个问题没有一个正确答案。

于 2013-08-28T07:49:11.257 回答
2

据我所知,Python 中内部函数的主要优点是它们继承了封闭函数的作用域。因此,如果您需要访问主函数范围内的变量(例如参数或局部变量),则内部函数是可行的方法。否则,做任何你喜欢的事情和/或找到最易读的东西。

编辑:也 看到这个答案

于 2013-08-28T07:27:49.207 回答
2

所以我能理解的是你有一个很长的函数,比如:

def long_func(blah, foo, *args):
    ...
...
my_val = long_func(foo, blah, a, b, c)

你所做的是:

def long_func(blah, foo, *args):
    def short_func1():
        ...
    def short_func2():
        ...
    ...
    short_func1()
    short_func2()
    ...
...
my_val = long_func(foo, blah, a, b, c)

您有更多选择,我将列出两个:

  1. 把它变成一个类

    class SomeName(object):
        def __init__(self, blah, foo, *args):
            self.blah = blah
            self.foo = foo
            self.args = args
            self.result = None  # Might keep this for returning values or see (2)
    
        def short_func1(self):
            ...
        def short_func2(self):
            ...
        def run(self):  # name it as you like!
            self.short_func1()
            self.short_func2()
            return self.result  # (2) or return the last call, on you
    ...
    my_val = SomeName(foo, blah, a, b, c).run()
    
  2. 制作另一个模块并将其short_funcs放入其中。就像 flyx 建议的那样。

    def long_func(foo, blah, *args):
        from my_module import short_func1, short_func2
    
        short_func1(foo)
        short_func2(blah)
    
于 2013-08-28T12:34:50.993 回答
0

好的做法是保持较低的循环复杂度。这实际上意味着将您的长函数分解为许多较小的函数。

复杂性通过 if、while、do、for、?:、catch、switch、case 语句以及运算符 && 和 || 的数量来衡量。(加一)在构造函数、方法、静态初始化程序或实例初始化程序的主体中。它是通过源的最小可能路径数量的度量,因此是所需测试的数量。一般 1-4 被认为是好的,5-7 可以,8-10 考虑重构,11+ 现在重构!

我建议采纳这个来自代码质量分析工具 Sonar 的建议。重构此类代码的一个好方法是使用 TDD。首先编写单元测试以覆盖当前函数的所有执行路径。之后,您可以放心地重构,单元测试将保证您没有破坏任何东西。

另一方面,如果您的 long 函数很长,但圈复杂度已经很低,那么我认为该函数是否嵌套并不重要。

于 2013-08-28T07:38:03.677 回答