码迷,mamicode.com
首页 > Web开发 > 详细

Python学习之引用和对象

时间:2018-03-20 23:19:05      阅读:379      评论:0      收藏:0      [点我收藏+]

标签:

python学习中引用和对象是必须要掌握的重要知识点,今天和大家分享的就是这两部分内容,帮助大家快速掌握引用和对象相关操作。

python中变量名和对象是分离的

例子 1:

a = 1

这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1.

例子 2:

>>> a = 1

>>> id(a)

24834392

>>> a = ’banana’

>>> id(a)

139990659655312

第一个语句中, 2是储存在内存中的一个整数对象,通过赋值 引用a 指向了 对象 1

第二个语句中,内存中建立了一个字符串对象‘banana’,通过赋值 将 引用a 指向了 ‘banana’,同时,对象1不在有引用指向它,它会被python的内存处理机制给当我垃圾回收,释放内存。

例子 3:

>>> a = 3

>>> b = 3

>>> id(a)

10289448

>>> id(b)

10289448

在这里可以看到 这俩个引用 指向了同一个 对象,这是为什么呢? 这个跟python的内存机制有关系,因为对于语言来说,频繁的进行对象的销毁和建立,特别浪费性能。所以在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。

例子 4:

>>> a = 4

>>> b = a

>>> id(a)

36151568

>>> id(b)

36151568

>>> a = a+2

>>> id(a)

36151520

>>> id(b)

36151568

可以看到 a 的引用改变了,但是 b 的引用未发生改变;a,b指向不同的对象; 第3句对 a 进行了重新赋值,让它指向了新的 对象6;即使是多个引用指向同一个对象,如果一个引用值发生变化,那么实际上是让这个引用指向一个新的引用,并不影响其他的引用的指向。从效果上看,就是各个引用各自独立,互不影响。

例子 5:

>>> L1 = [1,2,3]

>>> L2 = L1

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

>>> L1[0] = 10

>>> id(L1)

139643051219496

>>> id(L2)

139643051219496

>>> L2

[10, 2, 3]

同样的跟第四个例子那样,修改了其中一个对象的值,但是可以发现 结果 并不与 第四个栗子那样, 在本次实验中,L1 和 L2 的引用没有发生任何变化,但是 列表对象[1,2,3] 的值 变成了 [10,2,3](列表对象改变了)

在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。

原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)

列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。

而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。

我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

例子 6:

l = [1,2,3]

for item in l:

item = 8

# 这里只是让item指向l[i]所指向的对象,item = 8,则item指向新的对象8,不改变l[i]

print(l) # [1,2,3]

for i in range(len(l)):

l[i] = 8

# 这里令l[i]指向新的对象 8

print(l) # [8,8,8]

例子 7:

l2 = []

b = [1,2,3]

for i in range(1,5):

b[1] = i

l2.append(copy.copy(b))

# l2.append(copy.deepcopy(b)) 和copy.copy()结果一样

print(l2) # [[1, 1, 3], [1, 2, 3], [1, 3, 3], [1, 4, 3]]

copy.copy() 浅拷贝。只拷贝父对象,不会拷贝对象的内部的子对象。

那么,copy.copy()和copy.deepcopy()有什么区别呢?

l2 = []

b = [1,[4,5],3]

for i in range(1,5):

b[1][0] = i

l2.append(copy.copy(b)) # [[1, [4, 5], 3], [1, [4, 5], 3], [1, [4, 5], 3], [1, [4, 5], 3]]

# l2.append(copy.deepcopy(b)) # [[1, [1, 5], 3], [1, [2, 5], 3], [1, [3, 5], 3], [1, [4, 5], 3]]

print(l2)

例子 8:

函数的参数传递探究

def testPara(aList):

aList[0] = 8

print("inside function",aList) # [8, 2, 3]

if __name__ == ’__main__’:

l1 = [1,2,3]

testPara(l1)

print(l1) # [8, 2, 3]

def testPara(aList):

aList = [1,2]

print("inside function",aList) # [1,2] aList重新指向一个新的对象

if __name__ == ’__main__’:

l1 = [1,2,3]

testPara(l1)

print(l1) # [1, 2, 3]

这里要想直接把l1在函数内改变,可以在函数return l1

def test(l:list):

l.pop(0)

if __name__ == ’__main__’:

l = [1,2,3]

test(l)

print(l) # [2,3]

 

 

来源:推酷

Python学习之引用和对象

标签:

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
jiangjie190
加入时间:2016-02-19
  关注此人  发短消息
文章分类
jiangjie190”关注的人------(0
jiangjie190”的粉丝们------(0
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!