Python 中的嵌套函数

发布于 2024-08-08 09:52:33 字数 510 浏览 4 评论 0原文

使用这样的 Python 代码我们可以得到什么好处或含义:

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

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

What benefit or implications could we get with Python code like this:

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

I found this in an open-source project, doing something useful inside the nested function, but doing absolutely nothing outside it except calling it. (The actual code can be found here.) Why might someone code it like this? Is there some benefit or side effect for writing the code inside the nested function rather than in the outer, normal function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

爱本泡沫多脆弱 2024-08-15 09:52:33

通常,您这样做是为了创建闭包

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

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

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

Normally you do it to make closures:

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

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

Inner functions can access variables from the enclosing scope (in this case, the local variable x). If you're not accessing any variables from the enclosing scope, they're really just ordinary functions with a different scope.

吲‖鸣 2024-08-15 09:52:33

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

玩具示例:

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

Aside from function generators, where internal function creation is almost the definition of a function generator, the reason I create nested functions is to improve readability. If I have a tiny function that will only be invoked by the outer function, then I inline the definition so you don't have to skip around to determine what that function is doing. I can always move the inner method outside of the encapsulating method if I find a need to reuse the function at a later date.

Toy example:

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()
乜一 2024-08-15 09:52:33

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

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)

One potential benefit of using inner methods is that it allows you to use outer method local variables without passing them as arguments.

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)

can be written as follows, which arguably reads better

def save(item, resultBuffer):

  def helper(feature):
    resultBuffer.print(feature)
    resultBuffer.printLine()
    resultBuffer.flush()

  helper(item.description)
  helper(item.size)
  helper(item.type)
ヤ经典坏疍 2024-08-15 09:52:33

我无法想象这样的代码有什么好的理由。

也许旧版本中的内部功能是有原因的,就像其他操作一样。

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

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)

但是内部函数应该是(“私有”)类方法:

class some_class(object):
    def _add(self, x, y):
        return x + y
    def doOp(self, x, y):
        return self._add(x,y)

I can't image any good reason for code like that.

Maybe there was a reason for the inner function in older revisions, like other Ops.

For example, this makes slightly more sense:

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)

but then the inner function should be ("private") class methods instead:

class some_class(object):
    def _add(self, x, y):
        return x + y
    def doOp(self, x, y):
        return self._add(x,y)
浪荡不羁 2024-08-15 09:52:33

本地方法背后的想法与本地变量类似:不要污染更大的名称空间。显然,好处是有限的,因为大多数语言也不直接提供此类功能。

The idea behind local methods is similar to local variables: don't pollute the larger name space. Obviously the benefits are limited since most languages don't also provide such functionality directly.

拧巴小姐 2024-08-15 09:52:33

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

Are you sure the code was exactly like this? The normal reason for doing something like this is for creating a partial - a function with baked-in parameters. Calling the outer function returns a callable that needs no parameters, and so therefore can be stored and used somewhere it is impossible to pass parameters. However, the code you've posted won't do that - it calls the function immediately and returns the result, rather than the callable. It might be useful to post the actual code you saw.

亚希 2024-08-15 09:52:33

在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

In Python, you can use a nested function to create a decorator like @decorator. *My answer explains more about decorators.

I created multiply_by_5() to use it as the decorator for sum() as shown below:

# (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)

Output:

50

The code below is the case of not using the decorator:

# (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)

Or:

# (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)

Output:

50
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文