由于没时间系统学习下Python
只能见一个问题探究一个问题了
一、初级 - 对象
关于Python中的数据类型,今天重新认识了下。【参考】
首先,Python中,对象才有类型, 变量是没有类型的,它只是对象的“引用”。
其次,Python中对象被分为两类:可更改对象和不可更改对象(包括numbers, strings, tuples)。
a = 1 #一个指向int数据类型的a(再次提醒,a没有类型) list_a = [1] #一个指向list类型对象的list_a ,这个list中包含一个int对象1 a = 2 # a指向一个新的int对象,其值为2。内存中原始的1对象因为不能改变,于是被“抛弃” list_a[0] = 2 #list_a指向的list类型对象的第一个元素指向一个新的int对象,原来的对象1被抛弃。
因此,Python中的函数参数传递也分为两类:
1.不可变对象参数调用
def ChangeInt( a ):
a = 10
nfoo = 2
ChangeInt(nfoo)
print nfoo #结果是2
2.可变对象参数调用
def ChangeList( a ):
a[0] = 10
lstFoo = [2]
ChangeList(lstFoo )
print lstFoo #结果是[10]
二、进阶 - 拷贝
先理解深浅拷贝的概念:
-
浅拷贝
- 所谓的浅拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间.
- 浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的时候,指向这个内存空间的所有指针需要重新定义,不然会造成野指针错误
-
深拷贝
- 所谓的深拷贝指拷贝对象的具体内容,其内容地址是自助分配的,拷贝结束之后,内存中的值是完全相同的,但是内存地址是不一样的,两个对象之间相互不影响,也互不干涉.
认真理解 图解Python深拷贝和浅拷贝 中的例子,应该就可以进阶了我猜
1.对象赋值, wilber = will ,之后只要通过will改动其所指向的对象中的元素,wilber所指的对象中的元素就会随之改变;反之(通过wilber进行改动)亦然。
·但如果will指向的是不可更改对象,那么will的改动只会让它自己指向新的内存,而wilber不会改变(直接从“赋值”的角度想就可以了)
·如果will指向的是可变更对象,那wilber = will 就相当于是给这个对象起了个“别名”,彼此的改动都互相影响(想起当初的C++了…)
2.浅拷贝,wilber = copy.copy(will),之后通过will改动其所指向的对象中的元素,看被改变的元素是可更改对象还是不可更改对象:
·如果是可更改对象,那wilber所指的对象中的元素随其发生改变;
·如果是不可更改对象,那么wilber不会发生改变(看例子中的图,一目了然)。
反之亦然。
# 其实从这个角度思考更方便明了些,但没上面这种透彻
3.深拷贝,wilber = copy.deepcopy(will),二者之间的改动互不相干(虽然Python的设计是将will和wilber分别所指对象中的可更改对象共享了,但事实上只要改变了这些就会被重新赋值,我猜这只是Python用来节约内存的一个技巧,不要被这个搞混了)。
三、扩展
global关键字 - Python的global语句使用
Python中定义函数时,若想在函数内部对函数外的变量进行操作,就需要在函数内部声明其为global。
在不将函数外的变量指针加入参数列表的情况下,函数想要改变函数外的变量,可考虑使用global关键字