为啥嵌套函数可以从外部函数访问变量,但不允许修改它们[重复]

Posted

技术标签:

【中文标题】为啥嵌套函数可以从外部函数访问变量,但不允许修改它们[重复]【英文标题】:Why nested functions can access variables from outer functions, but are not allowed to modify them [duplicate]为什么嵌套函数可以从外部函数访问变量,但不允许修改它们[重复] 【发布时间】:2012-08-12 19:32:14 【问题描述】:

在下面的第二种情况下,Python 尝试查找局部变量。当它找不到时,为什么它不能像第一种情况那样在外部范围内查找?

这会在本地范围内查找 x,然后在外部范围内查找:

def f1():
    x = 5
    def f2():
         print x

这给出了local variable 'x' referenced before assignment 错误:

def f1():
    x = 5
    def f2():
        x+=1

我不能修改函数 f2() 的签名,所以我不能传递和返回 x 的值。但是,我确实需要一种方法来修改 x.有没有办法明确告诉 Python 在外部范围内查找变量名(类似于 global 关键字)?

Python 版本:2.7

【问题讨论】:

python 3 为此提供了nonlocal,但我认为值得一问为什么需要这样做。这比使用global 安全一点,但仍然感觉不对。 @mgilson 这样做有很多很好的理由,例如pep-3104 中的基本原理部分。 你用的是什么版本的python? @soulcheck 我使用 Python 2.7,在我的问题中对其进行了编辑。 @Dhara 抱歉,不知道为什么会发布评论。很明显,您使用的是 2.7。 【参考方案1】:

在 Python 3.x 中这是可能的:

def f1():
        x = 5
        def f2():
                nonlocal x
                x+=1
        return f2

this 帖子中给出了 Python 2.x 的问题及其解决方案。此外,请阅读PEP 3104 了解有关此主题的更多信息。

【讨论】:

我刚刚查了一下。 nonlocal 是这里使用的语句。 在 python 2.x 中使用全局而不是非本地 @user1320237 global 不能代替 nonlocal 工作——这正是我的问题!【参考方案2】:
def f1():
    x =  'value': 5 
    def f2():
        x['value'] += 1

解决方法是使用可变对象并更新该对象的成员。有时,名称绑定在 Python 中很棘手。

【讨论】:

这行得通,尽管我最终使用了一个包含单个元素的列表而不是字典。谢谢! 我觉得用nonlocal或者global比较正确 全局不是一个好主意,因为它会污染全局命名空间。 Nonlocal 是 python 3 的一个特性,这个问题指定了 python 2.7。 global 在 py2.7 中不能用于问题目的,但是 x['value']value 更难写在父作用域上,所以考虑将值传递给嵌套函数,然后将 value 从嵌套范围返回到父范围

以上是关于为啥嵌套函数可以从外部函数访问变量,但不允许修改它们[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何从 main() 函数外部访问 argv[]?

为啥 dolphindb 脚本中的函数无法访问外部范围内的变量

Python的闭包和装饰器

内部函数能够访问外部函数的局部变量,这个特性是闭包(Closure)编程的基础

11函数进阶---闭包

python中使用闭包及修改外部函数的局部变量