Python陷阱–参数-可变类型

Python陷阱–参数-可变类型

1 前言

当方法参数为可变类型时,可能会导致预期之外的执行结果。这种不会抛出异常的错误,需要我们日常积累经验、提升对python语言的理解,从而去避免错误的发生。

举个栗子

def function(li = []):
    li.append(1)
    print(li)

function()
function()

[1]
[1, 1]

是不是和其他语言不同,导致这一切发生的原因在于,Python是解释性语言,其形参在方法定义时就已分配内存空间,所以对于可变型数据而言,方法的两次调用过程中,形参指向同一内存单元。

2 分析

先看可变类型的分析:

from  random import choice

def function1(li = []):
    print("The id of li is:", id(li))
    li.append(choice([[2], [22], [222]]))
    print("The id of li is:", id(li))
    print("The value of li is:",li)
    
The id of li is140338997097608
The id of li is140338997097608
The value of li is[[222]]
The id of li is140338997097608
The id of li is140338997097608
The value of li is[[222], [222]]

对于可变类型,形参li存储的其实是一个列表的引用,列表是可变类型,当其内容变化时li中存储的引用(即地址值)不会变化,故而下次调用方法function1时,li指向的是上次修改过后的列表,即li=[1],不再是空列表了。

不可变类型分析:

from  random import choice

def function2(string = ""):
    print("The id of string is:", id(string))  #修改前id
    string += choice(["2", "22", "222"])
    print("The id of string is:",id(string))   #修改后id
    print("The value of string is:",string)
    
The id of string is139992122702512
The id of string is139992121910248
The value of string is2
The id of string is139992122702512
The id of string is139992121026688
The value of string is22

对于不可变类型如字符串,第一次执行function2时,字符串的值发生改变,所以string指向另一块存储空间**[2]。与可变类型参数的另一点不同在于,第二次执行方法function2时,参数string**指向初始的内存空间。具有“记忆性”,这一点与其他语言类似。

对于函数function2有一个有趣的现象,上面两次执行结束后字符串不同(“2"和"22”),若字符串相同比如均为"22"那么,出于底层的优化效果二者id值相同。类似的python中所有[-5, 256]的整数,其id均相同,一种优化(有兴趣的话了解一下时间、空间相似性)。

3 小结

简言之,可变类型做参数时,由于前后调用过程中指向同一块内存空间(id值不变),所以其修改效果会”保留“。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值