如何在一个python函数内部修改全局变量

在python函数内部修改全局变量,需要使用global关键字,这样的答案只是一个粗浅的理解,实际上,我们还要考虑全局变量的类型,可变对象与不可变对象在这个问题上的处理方式以及理解方式是不一样的。

1. 函数内修改全局不可变对象

a = 10

def update_a():
    a = 20

update_a()
print(a)    # 10

上面这段代码,尝试在函数update_a内部修改全局变量a的值,最后的结果是失败的,原因在于在函数内部形成了一个局部作用域,在这个局部作用域里,执行a = 20这条语句时,其实是在局部作用域里创建了一个新的变量a, 并将20赋值给它, 与全局作用域里的变量a之间没有任何联系。

如果想要在函数update_a里修改全局作用域里的a,那么需要使用global关键字

a = 10

print(a, id(a), 1)

def update_a():
    global a
    a = 20
    print(a, id(a), 2)

update_a()
print(a, id(a), 3)

程序输出结果

10 4559579360 1
20 4559579680 2
20 4559579680 3

从效果上看,的确实现了对全局变量的修改,但是请注意看全局作用域a的内存地址,从最开始的4559579360变成了4559579680,这说明,程序在update_a函数里创建了一个局部变量a, 其内存地址是4559579680, 由于使用了global关键字, 因此,全局作用域里的变量a也指向了内存地址4559579680,这才是函数内部修改全局变量的本质,我们终究是没有修改全局变量所指向的那片内存区域,而是将改变全局变量的引用,使其指向了在函数内部创建的数据。

2. 函数内修改全局可变对象

a = {}

def update_a():
    a['python'] = 100

update_a()
print(a)   # {'python': 100}

在函数update_a内部,对全局变量a进行了修改,尽管没有使用global关键字,但是全局变量的值受到了函数的影响,这似乎与我们前面刚刚所学习的知识相矛盾。在理解这段代码时,要注意一个细节,在函数内部,我们没有对变量a进行任何修改,换一种阐述方式,我们没有对变量a进行赋值操作。

在函数内部所形成的局部作用域里,我们可以访问到全局作用域里的变量,所谓访问,就是可以读取,但是你不能对它重新赋值,重新赋值在函数结束以后是无效的,下面的代码将向你解释这种情形

a = {}

def update_a():
    a = {'python': 100}

update_a()
print(a)   # {}

在执行语句 a['python'] = 100 时,程序并没有修改全局变量a的指向,变量a的内存地址没有发生改变,所变化的是变量a所指向的这片内存地址的内容,多了一对key-value,在局部作用域里执行赋值语句则是在内存中创建一个对象并赋值给一个变量,这个变量在内存层面上指向这个新对象。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案