关闭本地值

Closing over a local value

我在 Google's Python styleguide 中阅读了以下内容:

"Avoid nested functions or classes except when closing over a local value".

"closing over a local value" 是什么意思?

完整的相关部分如下:

2.6 Nested/Local/Inner Classes and Functions

Nested local functions or classes are fine when used to close over a local variable. Inner classes are fine.

2.6.1 Definition

A class can be defined inside of a method, function, or class. A function can be defined inside a method or function. Nested functions have read-only access to variables defined in enclosing scopes.

2.6.2 Pros

Allows definition of utility classes and functions that are only used inside of a very limited scope. Very ADT-y. Commonly used for implementing decorators.

2.6.3 Cons

Instances of nested or local classes cannot be pickled. Nested functions and classes cannot be directly tested. Nesting can make your outer function longer and less readable.

2.6.4 Decision

They are fine with some caveats. Avoid nested functions or classes except when closing over a local value. Do not nest a function just to hide it from users of a module. Instead, prefix its name with an _ at the module level so that it can still be accessed by tests.

意思是除非你创建一个闭包。闭包是指自由变量引用封闭范围内的变量。例如:

def foo():
    bar = 42
    def baz():
        print(bar)
    return baz
foo()()

这将打印 42,因为 bazfoo 局部范围内变量 bar 的闭包。请注意,您甚至可以反省这一点:

f = foo()
print(f.__closure__)

因此,本质上,该指南告诉您仅当嵌套函数实际对某事有用时才使用嵌套函数,一个人为设计的小示例可以是函数工厂:

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

add2 = make_adder(2)
add5 = make_adder(5)

print(add2(1), add5(1))

add2add5n 上的闭包。

有些人可能想嵌套一个函数 只是 以在全局范围内隐藏它,例如:

def foo(n):

    def frobnicate(x, y):
        return x + y

    m = n + 42
    return frobnicate(m, 11)

风格指南说不要那样做,只做:

def frobnicate(x, y):
    return x + y

def foo(n):
    m = n + 42
    return frobnicate(m, 11)