0: Python初次认识,十分神奇。大一学完C,C++,Java后,发现Pyhon如此简单的不可思议,有一定基础的人,一天学完Python不是难事。今天在《Python自然语言识别》偶尔看到Python的神奇赋值原理,特别来打卡。
1:Python 的对象都是动态类型,其基础在于内部的指针灵活性。看到这大多数朋友应该明白了,python的赋值其实都是引用罢了。譬如
foo = ['Monty','Python}']
bar = foo
foo[1] = 'Bodkin'
bar
output: ['Monty', 'Bodkin']
大神略过:经过上面的铺垫,可能有小白不知道,什么是引用,我们可以看一副图(偷,居然还有翻译者的水印Orz)
如图所示, 列表foo是存储在3133位置的对象的引用。当我们赋值bar = foo, 实际上发生了仅仅是3133上的引用被复制。那
2: 那么顺利成章的,我们可以尝试区分 通过引用改变对象 和 改变引用 的区别。
#比如
empty = []
nested = [empty,empty,empty]
nested
[[], [], []]
2.1 通过引用改变一个引用对象,nested内容都会改变
nested[1].append('python')
print(nested)
#三个全变了
# 因为三个元素实际上只是统一链表的引用。
[['python'], ['python'], ['python']]
2.2 这次略复杂,改变对象后,改变引用
nested = [[]] * 3
nested[1].append('python')
nested[1] = ['monty']
print(nested)
for s in nested:
print(id(s))
# 关键要明白 通过一个对象引用修改一个对象与覆盖一个对象引用之间的区别
#通过 ID 可以查出哪个对象的差别;
[['python'], ['monty'], ['python']]
2145503910280
2145502525064
2145503910280
如上所示,改变引用仅仅使nested[1] = ['monty']
2.3 函数 Id():用于获取对象的内存地址,所以可以确认两个对象是否相同。
3 掌握了以上知识,那我们如何复制出一个独立的对象呢?
3.0 刚刚的问题,在python中可以使用copy.deepcopy()解决,提供了一个深复制的功能。使用时需要import copy
(深复制简单而言就复制一份一模一样的数据,在Java的对象复制也有涉及)
import copy
base = ['en']
foo = [base,base,base]
bar = copy.deepcopy(foo)
foo[1].append(['ns'])
print(foo)
print(bar)