Python中的嵌套函数

rks48beu  于 2022-11-26  发布在  Python
关注(0)|答案(7)|浏览(140)

我们可以从Python代码中得到什么好处或启示呢?

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

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

2g32fytz

2g32fytz1#

通常您这样做是为了使 closures

def make_adder(x):
    def add(y):
        return x + y
    return add

plus5 = make_adder(5)
print(plus5(12))  # prints 17

内部函数可以访问封闭作用域中的变量(在本例中是局部变量x)。如果你不访问封闭作用域中的任何变量,那么它们实际上只是具有不同作用域的普通函数。

klh5stk1

klh5stk12#

除了函数生成器(内部函数的创建几乎就是函数生成器的定义)之外,我创建嵌套函数的原因是为了提高可读性。如果我有一个很小的函数,它只能由外部函数调用,然后内联该定义,这样您就不必跳过来确定该函数的作用。如果以后需要重用函数,我总是可以将内部方法移到封装方法之外。
玩具示例:

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()
6qfn3psc

6qfn3psc3#

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

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)
vawmfj5a

vawmfj5a4#

我想不出有什么好的理由写这样的代码。
也许有一个原因的内部功能在旧的修订,像其他行动。
例如,下面这句话就更有意义了:

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)
euoag5mw

euoag5mw5#

局部方法背后的思想与局部变量类似:不要污染更大的名字空间。显然,由于大多数语言并不直接提供这样的功能,所以好处是有限的。

f45qwnt8

f45qwnt86#

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

rta7y2nd

rta7y2nd7#

在Python中,可以使用嵌套函数来创建装饰器,如@decorator。*我的答案解释了更多关于装饰器的内容。
我创建了multiply_by_5(),将其用作sum()的装饰器,如下所示:

# (4 + 6) x 5 = 50

def multiply_by_5(func):
    def core(*args, **kwargs):
        result = func(*args, **kwargs)
        return result * 5
    return core

@multiply_by_5 # Here
def sum(num1, num2):
    return num1 + num2

result = sum(4, 6)
print(result)

输出量:

50

下面的代码是不使用装饰器的情况:

# (4 + 6) x 5 = 50

# ...

# @multiply_by_5
def sum(num1, num2):
    return num1 + num2

f1 = multiply_by_5(sum) # Here
result = f1(4, 6)
print(result)

或者:

# (4 + 6) x 5 = 50

# ...

# @multiply_by_5
def sum(num1, num2):
    return num1 + num2

result = multiply_by_5(sum)(4, 6) # Here
print(result)

输出量:

50

相关问题