|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 无名似名 于 2015-11-17 10:50 编辑
此贴为系列帖子《没那么简单》之对象无名,请找引用,改掉c思维。
学习小甲鱼《python基础教程》中,有许多思考,觉得有必要记录下来,一方面备查,一方面同鱼油讨论,共同进步。
今天讨论的主题是:对象,引用,改掉c思维,python设计哲学。
先上代码,看看问题:
- def fun():
- a=[1,2,3]
- print('id(a):','id(a))
- return a
- b=fun()
- print('id(b)',id(b))
复制代码
此代码的用意在于查看函数中的变量生存时间,学过c的人习惯思维是:a列表的生存周期为整个函数的生存期,当运行完fun()以后a被自动销毁然后把其值在传出去付给b,理论上a的id地址和b的id地址不同,但结果呢
结果:'id(a)' 5691872
'id(b)' 5691872
为什么居然一样啊,难道是a在销毁的时候a对象清空,恰巧建立b的对象也用同样的地址么。多试验几次,结果居然地址都一样。
再贴一段代码:
- a=[1,2,3]
- print(a,'id(a)',id(a))
- def fun():
- a.append(4)
- print(a,'id(a)',id(a))
- return a
- b=fun()
- print(b,'id(b)',id(b))
复制代码
结果:[1, 2, 3] id(a) 6885824
[1, 2, 3, 4] id(a) 6885824
[1, 2, 3, 4] id(b) 6885824
都是同一个内存,他们肯定都是对一个对象在操作,那函数的return到底返回的是什么,以c思维是返回‘值’但这里明显是返回原对象。
结论:c中往往会盯着变量的内存来思维,但是在python中却不是这样,因为你根本找不到对象,你时刻打交道的是对象的引用,在第一个函数例子中,a对象自从被创建后从未被销毁过,函数结束后销毁的是a这个引用名,a的引用名生存期是整个函数的生存期,同样第二个例子中,只是把a对象的引用引进函数里,操作的还是同一个对象。
重要结论:python中对象与引用是分离的,对象的操作都是通过引用。
用上边的结论来讨论函数的按‘值’传参和按‘址’传参就不会乱了
下边上代码,得结论:
- a=[1,2,3]
- print(a,'id(a)',id(a))
- def fun(arg_a,arg_b):
- a=arg_a
- b=arg_a[:] #此处不是引用复制而是对象复制,新建了一个对象
-
- a.append(3) #此处对外部a对象进行加3操作,看打印地址可知
- del b[0] #把新建对象b删除一个项目,看后边地址可知
- print(a,'id(fun.a)',id(a))
- print(b,'id(fun.b)',id(b))
- return a,b
- another_a,another_b=fun(a,a)
- print(another_a,':id(another_a)',id(another_a)) #全局a的操作就跟c中的按‘址’操作一样
- print(another_b,':id(another_b)',id(another_b)) #全局a的操作就跟c中的按‘值’操作一样
复制代码
运行结果:
[1, 2, 3] id(a) 3084736
[1, 2, 3, 3] id(fun.a) 3084736 #按‘址’传递,地址没变
[2, 3] id(fun.b) 3087256 #按 ‘值’传递,新建了个对象
[1, 2, 3, 3] :id(another_a) 3084736
[2, 3] :id(another_b) 3087256
必须记住:python中的引用操作时刻要明白到底是‘新建了原对象的引用’还是‘用原对象创建了个一样的新对象’。单等号‘=’操作一般都是引用复制给引用,不会改变原对象,而对象创建新对象用切片[:]或者对象内置函数copy(),这里边还有浅拷贝和深拷贝之分,鱼油自行研究吧
另外以上讨论有个前提:都是可变对象,要是换成字符串,元组,数字等不可变对象,就更简单了,不可变所以每次都是新建了个对象,不可能出现一个不可变对象有两个引用。
不知道鱼油能明白我的讨论不,从c进入python的一定要记住python处处是对象,处处是引用。
另外就是不得不佩服python的设计哲学,变量与对象分离,这真是个绝妙的点子,通过对引用的操作来处理对象,而对象你压根不需要知道存储在哪。而整个程序你只需关心’引用‘不需要关心’对象‘。
来个下期预告,会对元类,类,对象进行讨论,到时会用python的内置函数来一探这些东西里到底有什么,创建的时候到底发生了什么事,因为时间有限,我会在有空的时候一点一点的码出来。 |
|