Python 参数传递、返回值与拷贝机制解析

向北走
向北走
发布时间:2026-10-13 | 3人浏览过
原创

本文解析 Python 中参数传递、返回值及对象拷贝的核心机制。针对不可变对象(如数字、元组),其行为类似值传递;针对可变对象(如列表、字典),直接赋值与浅拷贝会共享引用,而深拷贝则创建独立副本。通过代码示例阐明不同操作对内存地址及数据修改的影响。

Python 参数传递机制

Python 的参数传递机制

在 Python 中,参数传递方式并非由用户直接控制引用传递或值传递,而是取决于对象类型。对于不可变对象(包括数字、字符串、元组等),参数传递的表现更接近于值传递;而对于可变对象(如列表、字典等),其行为则更接近于引用传递。


def fun1(n):
  print(n)  # n在没修改前,指向的地址和main函数中n指向的地址相同
  n = 20   # n在修改后,指向的地址发生改变,相当于新建了一个值为20的参数n
def fun2(l):
  print(l)  # l在没修改前,指向的地址和main函数中l指向的地址相同
  l = [5,6,7,8,9] # l在修改后,指向的地址和main函数中l指向的地址仍相同,此时main函数中l的值也会改变
if __name__=="__main__":
  n = 10
  l = [1,2,3,4,5]
  fun1(n)
  fun2(l)
  print(n)  # n的值还是10
  print(l)  # l的值在fun2()中已经被改变

Python 返回值机制

Python 的返回值机制

Python 函数返回值的处理同样无法强制指定为引用或值传递,其效果依对象类型而定。若返回不可变对象(如数字、字符串、元组等),效果类似于值传递;若返回可变对象(如列表、字典等),效果则类似于引用传递。


str1 = 'hi'
l1 = [1,2,3,4,5]
def fun1():
  return str1
def fun2():
  return l1
str2 = fun1() # 此时,str1 和 str2 的指向地址是相同的
str2 = 'hello' # 修改后,str2 指向的地址发生改变,相当于新建了一个值为`hello`的变量
l2 = fun2() # 此时,l1 和 l2 的指向地址是相同的
l2 = [6,7,8,9] # 修改后,l2 指向的地址仍相同,修改 l2 会影响到 l1

浅拷贝与深拷贝的区别

Python 的浅拷贝与深拷贝

在处理不可变对象(如数字、字符串、元组等)时,直接赋值的结果与深拷贝的效果一致。然而,对于可变对象(如列表、字典等),直接赋值、浅拷贝和深拷贝会产生不同的结果,具体差异需结合内存引用关系进行区分。


# 不可变对象(数字、字符、元组等)的例子
a = 100 
b = a
b = 30
print('a: ', a)
print('b: ', b)
# 结果:
# a = 100
# b = 30
# 可变对象(列表、字典等)的例子
import copy
dict1 = {1:1, 'user':'test', 'num':[1, 2, 3]}
dict2 = dict1 # 直接赋值,两个字典指向地址一致
dict3 = dict1.copy() # 浅拷贝,只拷贝到原对象
dict4 = copy.deepcopy(dict1) # 深拷贝,除了拷贝原对象,也会拷贝子对象
dict1[1] = 11
dict1['user'] = '123'
dict1['num'].remove(1)
print('原字典修改后:',dict1)
print('直接赋值:',dict2)
print('浅拷贝:',dict3)
print('深拷贝:',dict4)
# 结果
# 原字典修改后:{1:11,'user': '123', 'num': [2, 3]}
# 直接赋值:{1:11,'user': '123', 'num': [2, 3]}
# 浅拷贝:{1:1,'user': 'test', 'num': [2, 3]}
# 深拷贝:{1:1,'user': 'test', 'num': [1, 2, 3]}

总结

以上内容介绍了 Python 中关于参数传递、返回值以及浅拷贝和深拷贝的相关知识,旨在帮助读者理解其工作原理。如有任何疑问,欢迎留言交流,我们将及时回复。感谢大家对本站的支持! 如果您觉得本文对您有帮助,欢迎转载,请注明出处,谢谢!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表