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

时间:2017-01-08 18:08:42

标签: python

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

在上面的示例中,myList仍然是变异的,尽管它是非全局的并且不是通过参数传递的。但是,如果变量不是列表,则不起作用。

2 个答案:

答案 0 :(得分:2)

范围规则大致如下:

  • 本地范围:您在函数
  • 中定义变量
  • 封闭范围:您的函数位于另一个函数(或多个函数层)中,其中一个较高(封闭)函数声明了变量
  • 全球范围:全球范围(模块或文件)
  • 内置:Python原生的任何内置值

这被称为LEGB规则。

在您的情况下,这是因为您没有为myList内的名称foo()分配值。您只是为现有列表的0索引分配值。因此,myList的全局值是您正在使用的范围。

答案 1 :(得分:2)

但是,

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内您正在分配新的本地变量< / em> a shadows同名的全局变量。您将局部变量 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