You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

三层嵌套函数中最内层函数为何能访问最外层函数的命名空间?

为什么嵌套函数能访问外层函数的局部变量?

先看你写的这段测试代码:

>>> def f():
    f=['f',1,2]
    def g():
        g=1
        print('this prints out f from f(): ',f)
        print("id",id(f))
    def x():
        x=1
        print('this also prints out f from f():',f)
        print('id',id(f))
    x()
    g()
>>> f()
#output
this prints out f from f(): ['f', 1, 2]
id 140601546763464
this also prints out f from f(): ['f', 1, 2]
id 140601546763464

你的猜测完全正确!Python在查找变量时,封闭命名空间会递归遍历所有外层嵌套的函数作用域,这背后是Python的「作用域链(Scope Chain)」机制,核心遵循LEGB命名空间查找规则:

  • L(Local):优先查找当前函数的局部命名空间
  • E(Enclosing):如果局部没找到,就递归向外查找所有包裹当前函数的外层嵌套函数的命名空间
  • G(Global):接着查找模块级的全局命名空间
  • B(Built-in):最后查找Python内置的命名空间(比如print、len这类内置函数)

回到你的代码:x()和g()的局部作用域里没有定义f,所以Python自动向外遍历它们的封闭作用域——也就是包裹它们的f()函数的局部命名空间,在这里找到了f列表变量,因此能直接访问,不会报错。

这里补充个细节:如果在g()或x()里尝试给f赋值(比如f = [3,4,5]),Python会默认你是在当前函数的局部作用域定义新变量,而非修改外层的f;如果在赋值前先打印f,还会抛出UnboundLocalError(局部变量未定义就被引用)。要是想修改外层函数的f,需要用nonlocal关键字声明(Python 3+支持)。

总结来说,你观察到的现象完全符合Python的作用域规则,封闭命名空间本身就包含了所有外层嵌套的函数作用域,Python会逐层递归查找直到找到目标变量,或者遍历完所有作用域后抛出NameError。

内容的提问来源于stack exchange,提问作者spiritedExit0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:32:34