第九课:动态类型
1、在Python中,有一类特殊的对象,是专门用来存储数据的,常见的有数字、字符串、数列、字典等。这些对象是存储在内存中的实体,我们并不能直接接触到它们,在程序中接触的是对象名,是指向这些对象的引用(reference)。
2、
1)对象和引用分离,是动态类型的核心,引用可以随时指向一个新的对象
a = 3 a = ‘at‘
第一个语句中,3是内存中存储的整数对象,通过赋值,将引用a指向3;
第二个语句中,内存中建立对象‘at‘,将引用a指向了‘at‘,此时3没有引用指向它,Python中会自动将没有引用指向的对象销毁(destruct),释放内存(Python中对于小的整数和短字符串,会缓存,不会频繁建立和销毁)
2)
a = 10 b = a a = a+1
前两句,将a b指向同一个对象(b=a,是将b也指向a所指的对象),第三句将给a赋值,指向一个新的对象7,此时a b指向不同的对象。总结:如果多个引用指向同一个对象,若其中一个引用的值发生变化,其实这个引用是指向了一个新的对象,并不影响其它引用指向原来的对象。
l1 = [1,2,3] l2 = l1 l1[0] = 10 print l1,l2,l2[0] 输出: [10, 2, 3] [10, 2, 3] 10
【普通数据类型和复合数据类型是有区别的,复合数据类型是深拷贝,deepcopy()】如:
l1,l2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。
(与之形成对比的是,我们之前的赋值操作都没有改变对象自身,只是改变引用指向。)
3)
数列list可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。
之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object);元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.
3、从动态类型看函数参数传递
函数的参数传递,本质上传的是引用。比如:
def f(x): x = 100 print x a = 1 f(a) print a
参数x是一个新的引用,指向a所指的对象。如果参数是不可变(immutable)的对象,a和x引用之间相互独立。对参数x的操作不会影响a。这样的传递类似于C语言中的值传递。
如果传递的是可变(mutable)的对象,那么改变函数参数,有可能改变原对象。所有指向原对象的引用都会受影响,编程的时候要对此问题留心。比如说:
def f(x): x[0] = 100 print x a = [1,2,3] f(a) print a
总结
引用和对象的分离,对象是内存中储存数据的实体,引用指向对象。
可变对象,不可变对象
函数值传递
Python补充:第一课 数列list的方法
1、一些内建函数,可用于序列list、元组tuple、字符串
#s为序列
len(s):返回序列中元素的个数
max(s):返回序列中元素的最大值
min(s):返回序列中元素的最小值
all(s):返回True,若序列中元素都为True
any(s):返回True,若序列中任一元素为True
下面的方法主要起查询功能,不改变序列本身, 可用于表和定值表、字符串:
sum(s) 返回:序列中所有元素的和
# x为元素值,i为下标(元素在序列中的位置),可用于表和定值表
s.count(x) 返回: x在s中出现的次数
s.index(x) 返回: x在s中第一次出现的下标
由于定值表的元素不可变更,下面方法只适用于表:
# l为一个表, l2为另一个表
l.extend(l2) 在表l的末尾添加表l2的所有元素
l.append(x) 在l的末尾附加x元素
l.sort() 对l中的元素排序
l.reverse() 将l中的元素逆序
l.pop() 返回:表l的最后一个元素,并在表l中删除该元素
del l[i] 删除该元素
(以上这些方法都是在原来的表的上进行操作,会对原来的表产生影响,而不是返回一个新表。)
下面是一些用于字符串的方法。尽管字符串是定值表的特殊的一种,但字符串(string)类有一些方法是改变字符串的。这些方法的本质不是对原有字符串进行操作,而是删除原有字符串,再建立一个新的字符串,所以并不与定值表的特点相矛盾。
#str为一个字符串,sub为str的一个子字符串。s为一个序列,它的元素都是字符串。width为一个整数,用于说明新生成字符串的宽度。
str.count(sub) 返回:sub在str中出现的次数
str.find(sub) 返回:从左开始,查找sub在str中第一次出现的位置。如果str中不包含sub,返回 -1
str.index(sub) 返回:从左开始,查找sub在str中第一次出现的位置。如果str中不包含sub,举出错误
str.rfind(sub) 返回:从右开始,查找sub在str中第一次出现的位置。如果str中不包含sub,返回 -1
str.rindex(sub) 返回:从右开始,查找sub在str中第一次出现的位置。如果str中不包含sub,举出错误
str.isalnum() 返回:True, 如果所有的字符都是字母或数字
str.isalpha() 返回:True,如果所有的字符都是字母
str.isdigit() 返回:True,如果所有的字符都是数字
str.istitle() 返回:True,如果所有的词的首字母都是大写
str.isspace() 返回:True,如果所有的字符都是空格
str.islower() 返回:True,如果所有的字符都是小写字母
str.isupper() 返回:True,如果所有的字符都是大写字母
str.split([sep, [max]]) 返回:从左开始,以空格为分割符(separator),将str分割为多个子字符串,总共分割max次。将所得的子字符串放在一个表中返回。可以str.split(‘,‘)的方式使用逗号或者其它分割符
str.rsplit([sep, [max]]) 返回:从右开始,以空格为分割符(separator),将str分割为多个子字符串,总共分割max次。将所得的子字符串放在一个表中返回。可以str.rsplit(‘,‘)的方式使用逗号或者其它分割符
str.join(s) 返回:将s中的元素,以str为分割符,合并成为一个字符串。
str.strip([sub]) 返回:去掉字符串开头和结尾的空格。也可以提供参数sub,去掉位于字符串开头和结尾的sub
str.replace(sub, new_sub) 返回:用一个新的字符串new_sub替换str中的sub
str.capitalize() 返回:将str第一个字母大写
str.lower() 返回:将str全部字母改为小写
str.upper() 返回:将str全部字母改为大写
str.swapcase() 返回:将str大写字母改为小写,小写改为大写
str.title() 返回:将str的每个词(以空格分隔)的首字母大写
str.center(width) 返回:长度为width的字符串,将原字符串放入该字符串中心,其它空余位置为空格。
str.ljust(width) 返回:长度为width的字符串,将原字符串左对齐放入该字符串,其它空余位置为空格。
str.rjust(width) 返回:长度为width的字符串,将原字符串右对齐放入该字符串,其它空余位置为空格。