python模块传参_传值or传引用?一文明白Python的传参过程

原标题:传值or传引用?一文明白Python的传参过程

Python

本文作者:徐露露

本文编辑:胡 婧

技术总编:张学人

有问题,不要怕!访问

http://www.wuhanstring.com/uploads/5_aboutus/爬虫俱乐部-用户问题登记表.docx(复制到浏览器中)下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~

面试的时候,有没有被问到Python传参是传引用还是传值这种问题?有没有听到过Python传参既不是传值也不是传引用这种说法?其实在Python中讨论值传递还是引用传递是没有意义的,要真正对这些情况作出解释,其实是应该搞明白的是在Python对可变对象和不可变对象的赋值过程中,它是如何分配内存地址的。

比方说在实际操作过程中,我们遇到了如下问题:

l=[ 1, 2, 3]

defa(x):x=x+[ 4]

returnxa(l)print(l)

运行之后,结果居然不是[1,2,3,4],而依旧是[1,2,3]。这是为什么呢?

万物皆对象

无论是一个数字、字符串,还是数组、字典等,在Python中都会以一个对象的形式存在,并在Python中有一个唯一的内存地址。Python中的对象分为两类:可变对象和不可变对象。不可变对象指元组、字符串、数字等类型的对象,可变对象指的是字典、列表、自定义对象等类型的对象。举一个简单的例子,其中id()可以查看变量在内存中的地址:

list_1=[ 1, 2, 3]list_2=[ 1, 2, 3]a= 1

b= 1

print(id(list_1))print(id(list_2))print(id(a))print(id(b))

得到:

这说明,对于可变对象列表来说,即便列表内容一样,Python也会给它们分配新的不同的地址。然而,对于不可变对象数字来说,内存里只有一个1。即便再定义一个变量c=1,也是指向内存中同一个1。换句话说,不可变对象1的地址是共享的。

此外,我们对可变对象list_1进行修改:

list_1=[ 1, 2, 3]print(id(list_1))

defa(x):print(id(x)) x.pop() print(x) print(id(x)) x=x+[ 3] print(x) print(id(x))a(list_1)

得到:

可以发现,当调用x自身的方法pop后,x变为[1,2],但对象本身的标识并不会发生变化,只有当我们给它重新赋值给x之后,x的地址才会发生改变。也就是说,只有创建一个新的可变对象,Python才会分配一个新的地址。就算我们创建的新可变对象和已存在的旧可变对象完全一样,Python依旧会分配一个新的地址。

所以回到我们最初遇到的那个问题,如果想要得到[1,2,3,4],我们可以这样写:

l=[ 1, 2, 3]

defa(x):x=x+[ 4]

returnxl=a(l)print(l)

浅拷贝与深拷贝

在实际操作过程中,我本来想把修改前的a赋值给b,但是结果却发现b随着a的变化而发生了变化。

a = [ 1, 2, 3]b = aa.append( 4)print(a,b)print(id(a),id(b))

通过查看它们在内存中的地址,我们可以发现,a,b指向的是同一个地址,这也就解释了为什么a,b同时变化。如果我们想生成的b是一个新的对象的话,就可以使用copy模块。

importcopya = [ 1, 2, 3]b = copy.copy(a)a.append( 4)print(a,b)print(id(a),id(b))

这说明采用copy方式会将对象拷贝一份到新的内存地址中。但copy和deepcopy有什么区别呢?接着往下实验:

a = [ 1,[ 1, 2, 3], 3]b = copy.copy(a)a.append( 4)a[ 1].append( 4)print(a,b)print(id(a),id(b))print(id(a[ 1]),id(b[ 1]))

通过观察,可以发现子对象a[1]和b[1]指向的依旧是同一个内存地址。这说明,copy.copy只拷贝父类对象,不会拷贝对象内部的子对象。

如果我们想要完完整整地拷贝,就可以使用copy.deepcopy。

a = [ 1,[ 1, 2, 3], 3]b = copy.deepcopy(a)a.append( 4)a[ 1].append( 4)print(a,b)print(id(a),id(b))print(id(a[ 1]),id(b[ 1]))

关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。

1)必须原创,禁止抄袭;

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值