Python 嵌套函数作用域

Python 嵌套函数作用域,python,Python,为什么当a是不可变类型时,此代码不执行,但当它是可变类型时(例如,列表)会执行此代码?有一个关键字nonlocal,用于访问非局部变量。 nonlocal关键字用于处理嵌套函数中的变量,其中变量不应属于内部函数--w3schools.com 谢谢有一个关键字非局部,用于访问非局部变量。 nonlocal关键字用于处理嵌套函数中的变量,其中变量不应属于内部函数--w3schools.com 谢谢这是因为您没有从任何一个函数返回任何值,第二个a只是local到函数bar() 尝试使用非本地关键字,如

为什么当a是不可变类型时,此代码不执行,但当它是可变类型时(例如,列表)会执行此代码?

有一个关键字
nonlocal
,用于访问非局部变量。

nonlocal关键字用于处理嵌套函数中的变量,其中变量不应属于内部函数--w3schools.com


谢谢

有一个关键字
非局部
,用于访问非局部变量。

nonlocal关键字用于处理嵌套函数中的变量,其中变量不应属于内部函数--w3schools.com


谢谢

这是因为您没有从任何一个函数返回任何值,第二个
a
只是
local
到函数
bar()

尝试使用非本地关键字,如下所示:

def foo():
  a = 0
  def bar():
    nonlocal a
    a += 1
  bar()
foo()
输出

一,


这是因为您没有从任何一个函数返回任何值,而第二个
a
仅是
local
函数
bar()

尝试使用非本地关键字,如下所示:

def foo():
  a = 0
  def bar():
    nonlocal a
    a += 1
  bar()
foo()
输出

一,


我不认为其他答案能说明整个故事,所以这是我的2美分。

不同类型之间的范围没有区别。这不是这里发生的事情
重新绑定名称,无论该名称指的是什么,都会导致发生未绑定本地错误。

Python中的某些类型是可变的(一旦创建,就可以更改值),list就是其中之一。有些是不可变的,更改这些类型的值需要创建一个新对象

那么第一个例子,

def foo():
    a = 0
    def bar():
        nonlocal a
        a += 1
        return a
    return bar()
print(foo())
这不起作用,因为您实际上在这里有一个赋值,
a=a+1
。您可以使用
非本地
使上述工作正常进行,这不是重点

使用列表执行相同的操作:

def foo():
  a = 0
  def bar():
    a += 1
  bar()
foo()
这确实有效。这里没有作业。
不能将名称重新绑定到其他对象,但如果该对象是可变的,则可以修改其内容。

现在,还有两个案例需要注意

def foo():
  a = []
  def bar():
    a.append(1)
  bar()
foo()
这将起作用,但是您应该注意,
bar()
中的
a
现在是bar本地的,print()语句应该反映这一点。
但这里有个问题

def foo():
a=[]
def bar():
a=a+[1]#甚至a+=[1]都无所谓
bar()
印刷品(a)
foo()
这行不通!(将此代码段与第一个代码段进行对比非常重要,因为这说明了为什么这与作用域无关。请花一分钟时间再次阅读。)


所以这是行不通的,理解它很重要。
如果函数中有变量赋值,则该变量被视为局部变量

现在,在最后一个例子中,当我们做
a=c+1
时,它更像
a\u local=c\u nonlocal+1


在这种情况下,
a=a+1
a_local=a_local+1
,因此,这确实会导致错误

这就是为什么,重新绑定名称,无论该名称指的是什么,总是会导致发生未绑定的局部错误。
在前面的案例(第三个代码段)中,它没有重新绑定,而是创建了一个局部变量
在后一种情况下(第四个片段),实际上是重新绑定,因此出现了错误。

我认为其他答案并不能说明整个情况,所以这是我的2美分。

范围在不同类型之间没有区别。这不是这里发生的事情
重新绑定名称,无论该名称指的是什么,都会导致发生未绑定本地错误。

Python中的某些类型是可变的(一旦创建,就可以更改值),list就是其中之一。有些是不可变的,更改这些类型的值需要创建一个新对象

那么第一个例子,

def foo():
    a = 0
    def bar():
        nonlocal a
        a += 1
        return a
    return bar()
print(foo())
这不起作用,因为您实际上在这里有一个赋值,
a=a+1
。您可以使用
非本地
使上述工作正常进行,这不是重点

使用列表执行相同的操作:

def foo():
  a = 0
  def bar():
    a += 1
  bar()
foo()
这确实有效。这里没有作业。
不能将名称重新绑定到其他对象,但如果该对象是可变的,则可以修改其内容。

现在,还有两个案例需要注意

def foo():
  a = []
  def bar():
    a.append(1)
  bar()
foo()
这将起作用,但是您应该注意,
bar()
中的
a
现在是bar本地的,print()语句应该反映这一点。
但这里有个问题

def foo():
a=[]
def bar():
a=a+[1]#甚至a+=[1]都无所谓
bar()
印刷品(a)
foo()
这行不通!(将此代码段与第一个代码段进行对比非常重要,因为这说明了为什么这与作用域无关。请花一分钟时间再次阅读。)


所以这是行不通的,理解它很重要。
如果函数中有变量赋值,则该变量被视为局部变量

现在,在最后一个例子中,当我们做
a=c+1
时,它更像
a\u local=c\u nonlocal+1


在这种情况下,
a=a+1
a_local=a_local+1
,因此,这确实会导致错误

这就是为什么,重新绑定名称,无论该名称指的是什么,总是会导致发生未绑定的局部错误。
在前面的案例(第三个代码段)中,它没有重新绑定,而是创建了一个局部变量
在后一种情况下(第四个代码段),实际上是重新绑定,因此出现了错误。

但是您在哪里一直传递a,它的整数,并且在函数b中,a是未定义的?什么是“不执行”?此代码也不适用于列表<代码>+=i