Python中为什么函数可以返回一个内部定义的函数?

null
Python中为什么函数可以返回一个内部定义的函数?

14 回复

因为都是对象


这是Python的一个核心特性,叫做闭包。简单说,函数在Python里是“一等公民”,它本身就是一个对象,可以像整数、字符串一样被传递和返回。

当你写 def outer(): 里面又写了个 def inner(): 时,inner 这个函数对象是在 outer 的函数体里被创建出来的。outer() 执行完,返回的就是这个新创建出来的 inner 函数对象。

关键点在于,这个返回的 inner 函数能“记住”它被创建时所在的环境(也就是 outer 的局部作用域)。比如下面这个经典的计数器例子:

def make_counter():
    count = 0  # 这是外层函数的局部变量
    def counter():
        nonlocal count  # 声明我们要修改外层变量
        count += 1
        return count
    return counter  # 返回内部函数对象本身,而不是调用它

# 使用
my_counter = make_counter()
print(my_counter())  # 输出: 1
print(my_counter())  # 输出: 2
print(my_counter())  # 输出: 3

another_counter = make_counter()  # 创建一个全新的计数器
print(another_counter())  # 输出: 1 (独立的计数)

这里,每次调用 make_counter() 都会创建一个全新的 counter 函数实例,并且每个实例都“闭包”了自己独立的 count 变量。这就是闭包最实用的地方:它能让函数“拥有状态”,而这个状态对外又是隐藏的,是一种轻量级的封装。

所以,函数返回内部函数,本质上就是返回了一个可调用的对象,这个对象携带了它诞生时的上下文。这在实现装饰器、回调函数、延迟计算等模式时特别有用。

总结:函数是对象,返回它就是返回一个带状态的“行为包”。

看看 Python 的源码就知道了

#1 正解
万物皆对象
大 py 就是这么神奇

装饰器?

闭包函数的定义

closure

js 中的闭包是说用来在外面访问函数内部的变量。python 应该异曲同工之妙,其实写法非常像。

python 中所有的东西,在底层对应的是 Py_Object 的这个结构体指针,既然你可以返回比如字符串之类,为什么不能返回函数呢,大家都是 Py_Object* 呀。

这么说吧 如果不能这样 得多麻烦 全部专门定义一个累来返回实例么

这种结构叫闭包( encloser ),是函数式编程相关。因为 Python 里啥都是对象,如果用 C 写 Python 拓展就知道(虽然我没写过),不管啥都是 Py_object*,底层来看是一样的,就相当于根据外层函数的参数和运行定制了内层函数(也可以理解成成员变量)并返回。

函数式编程语言特性,函数是第一公民。函数和变量、对象这些都是同等处理的。

Python 有函数式编程特性。函数式编程里,函数是 first class,函数可以作为参数传入,也可以作为返回值返回,这样的函数一般叫高阶函数。如果你了解一下柯里化,就知道把函数作为值返回的作用。

另外可以了解下 Python 中的装饰器,用函数实现的装饰器,非常典型,把要装饰的函数作为参数,返回一个 wrapper 函数,而且它还是个闭包。

回到顶部