为什么Python函数能够改变非全局列表?

13 浏览
0 Comments

为什么Python函数能够改变非全局列表?

这个问题已经有了答案:

理解Python的对象传递风格的函数参数[重复]

myList = [5, 2]
def foo():
    myList[0] = 6

在上面的例子中,myList仍然被改变,虽然它不是全局的,也没有被作为参数传递。这不起作用的,如果变量不是列表。

admin 更改状态以发布 2023年5月21日
0
0 Comments

myList是一个全局变量。它存在于foo的上下文中,在那里您可以访问和修改其中一个元素。

myList = [0, 5]
def foo():
    myList[0] = 6
print('Before foo: {}'.format(myList))
foo()
print('After foo: {}'.format(myList))

输出

Before foo: [0, 5]
After foo: [6, 5]

然而,如果变量不是一个列表,这种方法就行不通。

我假设您尝试了类似以下的方法:

a = 0
def bar():
    a = 6
print('Before bar: {}'.format(a))
bar()
print('After bar: {}'.format(a))

输出

Before bar: 0
After bar: 0

在这种情况下,您不会观察到全局变量a的任何更改,因为在bar中,您正在分配一个新的局部变量a,它会遮蔽同名的全局变量。您将局部变量a设置为6,但这没有任何效果,因为变量在函数结束时就被丢弃了。

您可以通过运行类似以下的内容来展示即使在全局作用域中声明的简单整数也可以在函数作用域中访问。在这种情况下,我们指定函数应修改现有的全局变量b,而不是分配一个新的局部变量。

b = 0
def baz():
    global b
    b = 6
print('Before baz: {}'.format(b))
baz()
print('After baz: {}'.format(b))

输出

Before baz: 0
After baz: 6

0
0 Comments

作用域规则大致如下:

  • 局部作用域:在函数内定义变量
  • 闭合作用域:你的函数在另一个函数中(或多层函数中),并且其中一个更高的(闭合的)函数声明了变量
  • 全局作用域:全局作用域(模块或文件)
  • 内置作用域:Python中任何内置的原生值

这被称为LEGB规则。

在你的情况下,这是因为你没有将值赋给foo()内的myList名称。你只是给现有列表的0索引赋值。因此,你正在使用的是全局值myList的作用域。

0