代码之家  ›  专栏  ›  技术社区  ›  Hosam Aly

python中的嵌套函数

  •  76
  • Hosam Aly  · 技术社区  · 16 年前

    这样的python代码可以带来哪些好处或影响:

    class some_class(parent_class):
        def doOp(self, x, y):
            def add(x, y):
                return x + y
            return add(x, y)
    

    我在一个开放源码项目中发现了这一点,在嵌套函数内部做了一些有用的事情,但是除了调用它之外什么都不做。(可以找到实际代码 here 为什么会有人这样编码?在嵌套函数内部而不是在外部正常函数中编写代码有什么好处或副作用吗?

    6 回复  |  直到 11 年前
        1
  •  101
  •   Adam Rosenfield    16 年前

    通常你这样做是为了 closures :

    def make_adder(x):
        def add(y):
            return x + y
        return add
    
    plus5 = make_adder(5)
    print(plus5(12))  # prints 17
    

    内部函数可以从封闭范围访问变量(在本例中,是本地变量 x )。如果您没有从封闭范围访问任何变量,那么它们实际上只是具有不同范围的普通函数。

        2
  •  51
  •   Ross Rogers    11 年前

    除了函数生成器(内部函数创建几乎是函数生成器的定义)之外,我创建嵌套函数的原因是为了提高可读性。如果我有一个只由外部函数调用的小函数,那么我将内联该定义,这样您就不必跳过来确定该函数在做什么。如果我发现以后需要重用函数,我可以将内部方法移到封装方法之外。

    玩具示例:

    import sys
    
    def Foo():
        def e(s):
            sys.stderr.write('ERROR: ')
            sys.stderr.write(s)
            sys.stderr.write('\n')
        e('I regret to inform you')
        e('that a shameful thing has happened.')
        e('Thus, I must issue this desultory message')
        e('across numerous lines.')
    Foo()
    
        3
  •  24
  •   Kuba    13 年前

    使用内部方法的一个潜在好处是,它允许您使用外部方法局部变量,而不将它们作为参数传递。

    def helper(feature, resultBuffer):
      resultBuffer.print(feature)
      resultBuffer.printLine()
      resultBuffer.flush()
    
    def save(item, resultBuffer):
    
      helper(item.description, resultBuffer)
      helper(item.size, resultBuffer)
      helper(item.type, resultBuffer)
    

    可以写如下,可以说读起来更好

    def save(item, resultBuffer):
    
      def helper(feature):
        resultBuffer.print(feature)
        resultBuffer.printLine()
        resultBuffer.flush()
    
      helper(item.description)
      helper(item.size)
      helper(item.type)
    
        4
  •  8
  •   Jochen Ritzel    16 年前

    我想不出有什么好的理由来编写这样的代码。

    也许有一个原因,在旧版本的内部功能,像其他操作。

    例如,这使得 轻微地 更有意义:

    class some_class(parent_class):
        def doOp(self, op, x, y):
            def add(x, y):
                return x + y
            def sub(x,y):
                return x - y
            return locals()[op](x,y)
    
    some_class().doOp('add', 1,2)
    

    但是,内部函数应该是(“private”)类方法,而不是:

    class some_class(object):
        def _add(self, x, y):
            return x + y
        def doOp(self, x, y):
            return self._add(x,y)
    
        5
  •  6
  •   Kopernik VonC    16 年前

    局部方法背后的思想类似于局部变量:不要污染较大的名称空间。显然,这些好处是有限的,因为大多数语言都不直接提供这种功能。

        6
  •  1
  •   Daniel Roseman    16 年前

    你确定密码是这样的吗?这样做的正常原因是为了创建一个局部函数——一个带有烘焙参数的函数。调用外部函数返回一个不需要参数的可调用文件,因此可以存储和使用在不可能传递参数的地方。但是,您发布的代码不会这样做——它会立即调用函数并返回结果,而不是可调用的结果。发布您看到的实际代码可能很有用。