欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2021-02-14

程序员文章站 2022-03-13 12:14:47
...

对象引用,可变性和垃圾回收

变量

示例一:变量a和b引用同一个列表,不是那个列表的副本。

a=[1,2,3]
b=a
a.append(4)
print(b)
#输出的 结果为列表a的内容

2021-02-14
结果解析:只有列表a,b只同一个对象时,才能得出 以上结果。
示例二:创建对象之后,才会把变量分配给对象。

标识,相等性和别名

示例: 不同名称指同一个对象

charles={'name':'charles L.Dodgson','born':1832}
lewis=charles
print(lewis is charles)
输出结果:True
charles={'name':'charles L.Dodgson','born':1832}
lewis=charles
k=id(charles)
b=id(lewis)
print(k,b)
输出结果:
2588338597784 2588338597784

print((charles)
输出结果:{'name': 'charles L.Dodgson', 'born': 1832, 'balances': 950}

结果分析:结果为True,说明lewis和charles指代同一个对象。lewis可以说是字典的charles的别名。

例python中字典的两个别名比较是相等的,地址相等,但两个名字所指不相同。

charles={'name': 'charles L.Dodgson', 'born': 1832, 'balances': 950}
print(charles==lewis)
print(charles is not lewis)
输出 结果:
True
True

元祖的相对不可变性

示例:开始两个元祖t1,t2是 等相等的,一旦 改变了某个元祖内的元素,两者变得不相等。

t1=(1,2,[30,40])
t2=(1,2,[30,40])
print(t1==t2)
k=id(t1[-1])
print(k)
t1[-1].append(99)
t=id(t1[-1])
print(t1==t2)
输出结果:
True
2588338130248
False

结果分析:结果一为 true,结果三为false
t1不可变,t1[-1]可变。构建出来的t2,与t1元素相同,两者 是不同的对象,但是二者比较输出的结果相等.

默认做浅复制

可以通过使用内置的类型结构构造方法来复制列表的内容。

l1=[3,[55,44],(7,8,9)]
l2=list(l1)
print(l2)
print(l1==l2)
print(l2 is l1)
输出结果:
[3, [55, 44], (7, 8, 9)]
True
False

结果分析:list(l1)是创建列表l1的副本。副本跟源列表的内容相等,只不过两者指的是不同的对象。也可以使用l2=l1[:]来创建l1的副本。

示例:为一个包含另外一个列表

为任意对象做深复制和浅复制

示例:演示copy()和deepcopy()的用法,先定义一个简单的类,Bus这个类表示承载乘客的校车,在途中乘客会乘车会下车。定义乘客在途中下车和上车。

class Bus:
    def__init__(self,passers==None)
    if passers in None:
        self.passers=[]
    else:
        self.passers=list(passers)
    def pick(self,name):
        self.passers.append(name)
    def drop(self name):
        self.paasers.remove(name)

接下来创建一个Bus实例(Bus1)和两个副本,一个是浅复制副本,另外一个是深复制副本,观察实例Bus1学生下车后的结果。
1.使用copy和deepcopy产生的影响。

import copy 
bus1=Bus(['A1','Bill','Chaire','D1'])
bus2=copy.copy(bus1)
bus3=copy.deepcopy(bus1)
k1=id(bus1)
k2=id(bus2)
k3=id(bus3)
print(k1,k2,k3)
输出结果:
2588339326216 2588339335816 2588339335880

结果分析,深复制与浅复制的地址不同
1.使用copy和deepcopy,创建3个不同的Bus实例。
2.Bus1中Bill下车后,bus2中没有他。
3.观察passers属性之后,bus1和bus2共享同一个列表对象,因为bus2和bus1的浅复制副本。
4.bus3是bus1的深复制副本,因此它的passers属性指代另一个列表。

函数参数作为引用时

示例:函数可能会修改接收到的任何可变对象。

def f(a,b):
    a+=b
    return a
x=1
y=2
k=f(x,y)
print(k);
输出结果:3

推荐阅读