导语:本文章记录了本人在学习Python基础之面向对象篇的重点知识及我的心得,打算入门Python的朋友们能够来一块儿学习并交流。
本文重点:python
一、明确变量保存的是引用这一本质;
二、熟悉对象引用的基础知识;
三、掌握深复制和浅复制;
四、熟悉函数传参引用时潜在的麻烦并避免。
每一个变量都有标识、类型和值。对象一旦建立,它的标识毫不会变。
is运算符比较两个对象的标识;id()函数返回对象标识的整数表示,即对象的内存地址。当比较变量和单例值的时候应该用is。例如:X is None 或 X is not None。算法
is运算符比==要快,由于is不能重载。数据结构
指tuple数据结构的物理内容(即保存的引用)不可变。也就是说元组中不可变的是元素的标识,但元组的值会随着引用的可变对象变化而变化。
tuple,list,dict,set保存的是对象的引用,而str,byte,array.array保存的是对象的值(字符,字节,数字)。函数
浅复制:当复制tuple,list,dict,set时,副本之间共享内部对象的引用
。copy.copy()
深复制:当复制tuple,list,dict,set时,副本之间不共享内部对象的引用
。copy.deepcopy()学习
eg:浅复制小例子code
list1=[1,(55,66),[7,8,9]] list2=list(list1)#构建副本默认为浅复制 list2[1]+=(77,88)#对元组进行+=运算会解绑list2[1],并与右端运算后的值之间从新绑定起来。 list2[2]+=[10]#对列表进行iadd运算会就地修改列表,不会发生从新绑定。 list2[0]*=3 list1[2].pop(0) print(list1) print(list2)
#输出: [1, (55, 66), [8, 9, 10]] [3, (55, 66, 77, 88), [8, 9, 10]]
分析:list2是list1的副本,咱们对list2的三个元素均做了改动,但只有列表元素的改动影响到了list1。缘由在于list1和list2的第三个列表元素共享引用,所以影响也会同步;元组由于发生了解绑的运算因此影响未同步到list1
;至于数值的影响不一样步的缘由是由于浅复制针对str,byte,array.array这些对象直接将值从新保存到副本中来,不存在共享引用的内部逻辑。对象
深复制注意事项:内存
Python惟一支持的参数传递模式是共享传参。共享传参指函数的各个形式参数得到实参中各个引用的副本,即函数内部的形参是实参的别名。
资源
(2)所以在类中直接把参数赋值给实例变量以前必定要三思,由于这样会为参数对象建立别名,修改传入参数指向的可变对象。字符串
eg:函数修改做为参数传入的全局变量
def f(a, b): a += b return a a = [1, 2] b = [3, 4] f(a, b) print(a, b)#输出[1, 2, 3, 4], [3, 4],此时列表a已经发生变化。 t = (10, 20) u = (30, 40) f(t, u) print(t, u)#输出((10, 20), (30, 40)),此时元组t没有发生变化。
在Python中每一个对象的引用都会有统计。当引用计数归零时,对象就会当即销毁。
一、使用一个元组来构造另外一个元组,获得的实际上是同一个元组。
二、比较字符串或整数是否相等时,应该使用==而不是is。这是因为Python解释器内部驻留的特性所致使的。