为何Python函数会覆盖传入的全局变量值?
Python中函数参数修改全局变量的疑惑:可变与不可变对象的差异
你遇到的问题和变量作用域无关,核心是Python中不可变对象和可变对象的处理逻辑不同。
不可变对象:修改时创建新对象
像数字(int)、字符串(str)、元组(tuple)这类属于不可变对象,它们的值一旦创建就无法直接修改。当你把这类对象传入函数时:
- 函数参数
num拿到的是原对象的引用,但执行num +=2时,并不是修改原对象的值,而是创建了一个新的int对象(值为7),并让num指向这个新对象。 - 全局的
my_number仍然指向原来的5,所以它的值不会改变。
对应你的代码:
def add_two_to(num): num += 2 return num my_number = 5 new_number = add_two_to(my_number) # my_number 还是5,new_number是7
可变对象:直接修改原对象内容
列表(list)、字典(dict)这类属于可变对象,它们的内容可以被直接修改。当你把这类对象传入函数时:
- 函数参数
board和全局的game_board指向同一个列表对象。 - 执行
board[1] = 'X'时,是直接修改这个共享对象的内容,而不是创建新对象。所以无论是全局的game_board还是函数内的board,看到的都是修改后的结果。
对应你的代码:
def place_on_board(board): board[1] = 'X' return board game_board = [0,1,2] new_board = place_on_board(game_board) # game_board和new_board都指向同一个修改后的列表:[0,'X',2]
如何避免修改原可变对象
如果不想让函数修改全局的可变对象,可以在函数内部创建对象的副本,再对副本进行修改:
def place_on_board(board): # 创建列表的副本(两种常见方式) copied_board = board.copy() # 方法1 # copied_board = board[:] # 方法2(切片语法) copied_board[1] = 'X' return copied_board game_board = [0,1,2] new_board = place_on_board(game_board) # game_board仍然是[0,1,2],new_board是[0,'X',2]
内容的提问来源于stack exchange,提问作者David Bluhm
相关产品推荐
相关产品推荐

