Python中如何按引用传递变量

Python中如何按引用传递变量

技术背景

在Python里,参数传递的方式常常会让开发者感到困惑,尤其是与传统的按值传递或按引用传递概念对比时。Python采用的是按赋值传递的方式,这与参数是可变对象还是不可变对象密切相关。理解Python的变量传递机制,对于编写正确且高效的代码十分关键。

实现步骤

1. 理解可变和不可变对象

  • 可变对象:像列表、字典这类对象是可变的,在函数内部可以修改其内容。
  • 不可变对象:如字符串、整数等对象是不可变的,在函数内部无法修改其内容。

2. 传递可变对象

若传递的是可变对象,函数能直接修改该对象的内容。示例如下:

1
2
3
4
5
6
7
8
9
10
def try_to_change_list_contents(the_list):
print('got', the_list)
the_list.append('four')
print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

输出结果:

1
2
3
4
before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

3. 传递不可变对象

当传递不可变对象时,函数内部无法修改该对象。示例如下:

1
2
3
4
5
6
7
8
9
10
def try_to_change_string_reference(the_string):
print('got', the_string)
the_string = 'In a kingdom by the sea'
print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

输出结果:

1
2
3
4
before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

4. 模拟按引用传递

若要模拟按引用传递不可变对象,可采用以下方法:

  • 返回新值
1
2
3
4
5
6
7
def return_a_whole_new_string(the_string):
new_string = the_string.upper()
return new_string

my_string = 'hello'
my_string = return_a_whole_new_string(my_string)
print(my_string)
  • 使用包装类
1
2
3
4
5
6
7
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
new_string = stuff_to_change[0].upper()
stuff_to_change[0] = new_string

wrapper = ['hello']
use_a_wrapper_to_simulate_pass_by_reference(wrapper)
print(wrapper[0])

核心代码

传递可变对象

1
2
3
4
5
6
7
def try_to_change_list_contents(the_list):
the_list.append('new_item')
return the_list

outer_list = [1, 2, 3]
new_list = try_to_change_list_contents(outer_list)
print(new_list)

传递不可变对象并模拟按引用传递

1
2
3
4
5
6
7
def modify_wrapper(wrapper):
wrapper[0] = wrapper[0] * 2
return wrapper

wrapper = [5]
modify_wrapper(wrapper)
print(wrapper[0])

最佳实践

  • 当需要修改传入的对象时,使用可变对象(如列表、字典)。
  • 若要模拟按引用传递不可变对象,可使用返回值或包装类。
  • 在类的实例方法中,通过self访问和修改实例属性。

常见问题

1. 为什么在函数内部重新赋值参数,外部变量不受影响?

因为参数是按赋值传递的,函数内部的参数只是外部变量的一个引用副本。重新赋值参数只是让该副本指向了新的对象,而外部变量的引用并未改变。

2. 如何判断一个对象是可变还是不可变的?

可查看对象的文档或尝试修改对象。若修改操作会创建新对象,那么该对象是不可变的;若修改操作能直接改变对象的内容,那么该对象是可变的。


Python中如何按引用传递变量
https://119291.xyz/posts/2025-05-09.how-to-pass-a-variable-by-reference-in-python/
作者
ww
发布于
2025年5月9日
许可协议