python引用传参_备战Python面试(3) 变量与参数传递

4d992ee702a7cd9f2b09742d5d6033bc.png

1. 可更改(mutable)对象与不可更改(immutable)对象

Python的语言特性决定了变量是没有类型的,而类型如int,double都是对象。因此,所有变量都可以认为是内存中相应类型对象的引用。这里的面试点就是:类型是属于对象的,而不是变量

var=10  #var是一个变量,在赋值之前没有类型,赋值之后是int对象的引用

Python的类型对象可分为可更改(mutable)对象与不可更改(immutable)对象

  • 不可更改(immutable)对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。Python中的String字符串,Number数值类型(如int,double),Tuple元组都是不可更改的
  • 可更改(mutable)对象,该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。Python中的List列表,Dictionary字典,Set集合都是可更改的。

实验证明:

# id()函数输出变量的内存地址

var=10
print(var,id(var))
var=20
print(var,id(var))


mylist=[]
print(mylist,id(mylist))
mylist.append(10)
print(mylist,id(mylist))

2. Python函数传参

C/C++中函数传参分为值传递,引用传递。值传递后函数内部修改不会影响外部的值,但对引用传递的参数进行修改会同时改变外部的值。

Python的函数传参本质上都是类似值传递的复制方式,即将原始值的拷贝传递给函数。但由于变量存储的实际是类型对象的内存地址,所以可更改对象与不可更改对象在函数传参的表现并不相同。

2.1 不可更改对象

不可更改对象的函数传递仍旧表现为值传递,即内部的修改不会改变外部的值

var=10

def func(a):
    print("-------- in func --------")
    print("a init in func:",a,id(a))
    a=10
    print("a with save value:",a,id(a))
    a=20
    print("a with different value:",a,id(a))
    print("-------- end func --------")

print(var,id(var))
func(var)
print(var,id(var))

在上面的代码中由于var是数值类型,不可更改对象,所以a也是不可更改的。值传递后进入函数,var,a指向相同的内存地址。将a重新赋予相同的值也不会修改其指向的地址,因为值没变,所以类型对象的地址相同。当a赋予不同的值,则a的地址发生改变,但不会影响var的值和指向的内存地址。

2.2 可更改对象

可更改对象的函数传递虽然是值传递,但却表现为引用传递,即内部的修改会改变外部的值

mylist=[]

def func(templist):
    print("-------- in func --------")
    print("templist init in func:",templist,id(templist))
    # templist=[] 此操作可避免类似引用传递的效果,因为相当于将templist指向不同的地址
    templist.append(1)
    print("templist add value:",templist,id(templist))
    templist.append(2)
    print("templist add value:",templist, id(templist))
    print("-------- end func --------")

print(mylist,id(mylist))
func(mylist)
print(mylist,id(mylist))

在上面的代码中由于mylist是列表,可更改对象,所以templist也是可更改的。值传递后进入函数,mylist,templist指向相同的内存地址。当向templist添加值时,操作是允许的,因此地址不变,所以外部的mylist也会发生变化。(想要避免这样,可以在函数中重新赋值)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值