从词汇范围界定的Google Style Guide个例子中:

嵌套的Python函数可以引用封闭函数中定义的变量

这两个问题一开始似乎都得到了验证:

# Reference
def toplevel():
    a = 5
    def nested():
        print(a + 2)
    nested()
    return a
toplevel()
7
Out[]: 5

# Assignment
def toplevel():
    a = 5
    def nested():
        a = 7 # a is still 5, can't modify enclosing scope variable
    nested()
    return a
toplevel()
Out[]: 5

那么,为什么嵌套函数中引用和赋值的组合会导致异常呢?

# Reference and assignment
def toplevel():
    a = 5
    def nested():
        print(a + 2)
        a = 7
    nested()
    return a
toplevel()
# UnboundLocalError: local variable 'a' referenced before assignment

推荐答案

在第一种情况下,您指的是一个nonlocal变量,这是可以的,因为没有称为a的局部变量.

def toplevel():
    a = 5
    def nested():
        print(a + 2) # theres no local variable a so it prints the nonlocal one
    nested()
    return a

在第二种情况下,您创建了一个局部变量a,这也很好(局部变量a将不同于非局部变量,这就是为什么最初的a没有更改).

def toplevel():
    a = 5 
    def nested():
        a = 7 # create a local variable called a which is different than the nonlocal one
        print(a) # prints 7
    nested()
    print(a) # prints 5
    return a

在第三种情况下,您创建了一个局部变量,但在此之前有print(a+2)个,这就是引发异常的原因.因为print(a+2)将引用在该行之后创建的局部变量a.

def toplevel():
    a = 5
    def nested():
        print(a + 2) # tries to print local variable a but its created after this line so exception is raised
        a = 7
    nested()
    return a
toplevel()

为了实现你想要的,你需要在你的内在功能中使用nonlocal a:

def toplevel():
    a = 5
    def nested():
        nonlocal a
        print(a + 2)
        a = 7
    nested()
    return a

Python-3.x相关问答推荐

海象表达可以放在方括号中而不是括号中吗?

我的SELECT函数搜索的是列,而不是列中的数据.我怎么才能让它搜索数据呢?

如何使用PySide6创建切换框架?

Python VS Code 自动导入路径包含 src

添加任意数量的 pandas 数据框

如何沿单列获取嵌套列表中的唯一值?

将逗号分隔的字符串类型系列转换为整数列表 pandas

如何查找 tensorflow.python.data.ops.dataset_ops.MapDataset 对象的大小或形状,make_csv_dataset 的输出

如何准确测定cv2的结果.在BW/黑白图像中查找对象?

在python中循环处理时并行写入文件

`pyspark mllib` 与 `pyspark ml` 包

Pytorch:图像标签

python 3中的SQLAlchemy ER图

获取比较多列的最大值并返回特定值

无法在 macOS 上的 Anaconda3 python3.6 上安装 OpenCV3

Selenium (Python) - 使用 Chrome 网络驱动程序等待下载过程完成

接收导入错误:没有名为 *** 的模块,但有 __init__.py

在 WSL (Ubuntu) 中为 python3 安装 venv

为 Python 3 和 PyQt 构建可执行文件

哪个更有效:Python 文档字符串还是类型提示?