ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

《流畅的Python》Object References, Mutability, and Recycling--第8章

2019-12-15 11:02:37  阅读:304  来源: 互联网

标签:passengers Mutability format Python Recycling 对象 print id identity


Object References, Mutability, and Recycling

 

本章章节:

  • Variables Are Not Boxes
  • identity , Equality ,  Aliases
  • Copies are shallow by default
  • Function Parameters as references
  • del and Garbage Collection
  • Weak References
  • Tricks Python Plays with Immutable

Variables

翻译过来叫做变量,其实就是指针/标签。指向一个内存地址。而别名就是说同一个对象有多个标签。

identity

完全一样的两个对象,区别它们的是identity,Python使用id()函数得到一个对象的identity。

 

==符号是object.__eq__的语法糖。它会调用内存中的对象进行比较。

is符号是object.__id__的语法糖,只会比较对象的id,自然运行速度快于==。

 

Copies are shallow by default

tuple模式是浅层复制。使用list()或者copy()复制的是tuple内的第一层对象。

 

copy模块,深层复制

可用于深层的复制。

copy.copy(x)返回x层的浅层复制。

 

Function Parameters as References

call by sharing共享传参。这是Pyhon唯一支持的参数传递模式。Ruby等OO对象语言都是这种模式。

一个函数可以改变传递给它,作为参数的可变对象(multable object)的值,但不能改变对象的identity。

 

形式参数是别名:

例子:

def f(a, b):
    print(id(a), id(b))  #
    a += b
    print(id(a))
    return a

x = 1
print("id(x) is %s" % id(x))
y = 2
print("id(y) is %s" % id(y))
f(x, y)

 

id(x) is 4565326480
id(y) is 4565326512
4565326480 4565326512
4565326544

由此可知,x和a, y和b都是同一个对象的引用。所以说a, b只是别名。

而a += b代码中的a, 的id改变了。这代表它引用的是另一个不可变对象(整数)。

 

改变可变对象的值

对上面的例子进行修改:

def f(a, b):
    print(id(a), id(b))  #
    a += bprint("change variable a, but its id not change: {}".format(id(a)))
    return a

x = [1, 2]
print("id(x) is %s" % id(x))
y = [2, 3]
print("id(y) is %s" % id(y))
print("return is {}".format(f(x, y)))
print("x is {}".format(x))

 x是一个list,属于可变对象。

id(x) is 4545995264
id(y) is 4545996928
4545995264 4545996928
change variable a, but its id not change: 4545995264
return is [1, 2, 2, 3]
x is [1, 2, 2, 3]

由此验证了一个函数可以改变传递给它,作为参数的可变对象(multable object)的值,但不能改变对象的identity。

 

如果把x,y改成一个tuple,那么函数不能对x进行修改了。

 

call by share原理,不要把可变对象作为默认的参数。

这个原理体现了一些方便。但是:

class HauntedBus:
    def __init__(self, passengers = []):
        self.passengers = passengers

    def pick(self, name):
        self.passengers.append(name)
bus1 = HauntedBus()
bus1.passengers.append("Tom")
print("bus1 has {}".format(bus1.passengers))
bus2 = HauntedBus()
print("bus2 has {}".format(bus2.passengers))

结果竟然是:

bus1 has ['Tom']
bus2 has ['Tom']

 

 bus2也有了一个乘客Tom!

 原因就是因为它们共享了一个参数passengers,它是一个list类型,是可变参数。由于共享,所以出现了两个对象数据混淆的问题。

 背后的过程是:passengers = []是在模块加载时,定义函数的过程中被计算。

 

避免也简单,如果需要传入数据,在函数内进行复制,使用复制的数据。

 


 

 

 

 

 

 

 

 

 

 

 

 

 

标签:passengers,Mutability,format,Python,Recycling,对象,print,id,identity
来源: https://www.cnblogs.com/chentianwei/p/12042188.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有