Python对象类型
说明:python程序可以分解成模块,语句,表达式以及对象。
1)、程序由模块构成
2)、模块包含语句
3)、语句包含表达式
4)、表达式建立并处理对象
一、使用内置类型
除非有内置类型无法提供的特殊对象需要处理,最好总是使用内置对象而不是使用自己的实现。
二、python的核心数据类型
对象类型 例子 常量/创建
数字 1234,3.1414,999L,3+4j,Decimal
字符串 'diege',"diege's"
列表 [1,[2,'three'],4]
字典 {'food':'spam','taste':'yum'}
元组(序列) (1,‘span',4,'u')
文件 myfile=open('eggs'.'r')
其他类型 集合,类型,None,布尔型
还有模式对象,套接字对象等等。。其他的类型的对象都是通过导入或者使用模块来建立的。
由字符组成的字符串,由任意类型的元素组成的列表。这两种类型的不同之处在于,列表中的元素能够被修改,而字符串中的字符则不能被修改。换句话说,字符串的值是固定的,列表的值是可变的。元组的数据类型,它和列表比较相近,只是它的元素的值是固定的。列表和字典都可以嵌套,可以随需求扩展和删减。并能包含任意类型的对象。
Python中没有类型声明,运行的表达式,决定了建立和使用对象的类型。同等重要的是,一旦创建了一个对象。它就和操作结合绑定了--只可以对字符串进行字符串相关操作。对列表进行相关操作。Python是动态类型(它自动地跟踪你的类型而不是要求声明代码),但是它也是强类型语言(只能对一个对象性有效操作).
三、数字
整数,浮点,长整型等
支持一般的数学运算:+,- * % **(乘方)
5L,当需要有额外的精度时,自动将整型变化提升为长整型。
除表达式,python还有一些常用的数学模块和随机数模块
>>>import math
>>> dir(math)
>>> math.log(1)
0.0
>>> import random
>>> dir(random)
四、字符串
1、是一个个单个字符的字符串的序列。
>>> s[1]
'i
第一个字符的序列是0
>>> s[0]
'd
通过字符找到索引编号
>>> S.index('a')
0
除了简单的从位置进行索引,序列也支持一种所谓分片的操作。
>>> s='diege'
>>> s[1:3]
'ie'包括左边的位置不包括右边的位置
>>> s[:3]
'die'
开头到第三个(不包括第3个)
>>> s[3:]
'ge'
第三个到最后(包括第3个)
>>> s[:]
'diege'
所有
>>> s[-1]
'e'
倒数第1个
2、序列可以通过len()函数获取长度
>>> s='diege'
>>> len(s)
5
可以根据序列定位字符串里的字符,序列从0开始
>>> s[0]
'd
可以使用反向索引
>>> s[-1]
'e'
>>> s[len(s)-1]
'e'
3、作为一个序列字符串也支持+符号进行合并或者重复
>>> s+'xyz'
'diegexyz'
>>> s*3
'diegediegediege'
注意:+加好对于不同的对象有不同的意义:对于数字为加法,对于字符串为合并。
这是python的一般特性,多态,即一般操作的意义取决于被操作的对象。字符串具有不可变性,在创建后值不能改变。不能通过对其某一位置进行赋值而改变字符串。但是可以通过建立一个新的字符串并以同一个变量名对其进行赋值。因为python在运行过程中会清理旧的对象。
s='z'+s[1:]
4、查找替换
字符串的find方法是一个基本的子字符串查找操作。它将返回一个传入子字符串的位置,或者没找到的情况下返回-1而字符串的replace方法将会对全局进行搜索和替换。
>>> s.find('ie')
1
尽管这些字符串方法的命令有改变的含义,但是不会改变原始的字符串,而会是创建一个新的字符串作为结果,因为字符串具有不可变性。
>>> S=s.replace('ie','xyz')
>>> s
'diege'
>>> S
'dxyzge'
5、其他处理字符串的方法
通过分隔符将字符串分为子字符串(作为一种解析的简单形式),大小写变化,测试字符串的内容,去掉字符串后的空格符号
分隔
>>> line='aaa,bbb,ccc,ddd,ee'
>>> line.split(',')
['aaa', 'bbb', 'ccc', 'ddd', 'ee']
小写转换为大写
S='diege'
>>> S.upper()
'DIEGE'
大写转换为小写
>>> S='PYTHON'
>>> S.lower()
'python
测试字符串的内容
>>> S.isalpha()
True
删除字符串后面的空格
>>> line='aa,cc,dd\n'
>>> line=line.rstrip()
>>> line
'aa,cc,dd
6、寻求帮助
可以通过内置的dir函数,将返回一个列表,其中包含了对象的所有属性,由于方法是函数的属性,他们也会在这个列表中出现。
dir函数简单地给出方法的名称,查询他们做什么的,可以将其传递给help函数
>>> help(S.index)
python允许使用三个引号(三个单引号或双引号)中标识多行字符串的形式。在三个引号中可以使用换行,或者单双引号而无需转义。而只使用一个单引号或双引号需要转义。三个引号用于标识多行字符串形式。
7、模式匹配
导入正则表达式模块,用于搜索,分割,替换
>>> import re
>>> match=re.match('Hello[\t]*(.*)world','Hello Python world')
>>> match.groups()
(' Python ',)
>>> match.group()
'Hello Python world'
>>> match.group(1)
' Python '
>>> match=re.match('/(.*)/(.*)/(.*)','/usr/home/diege')
>>> match.groups()
('usr', 'home', 'diege')
五、列表
有时称呼序列
列表是一个任意类型的对象的位置相关的有序集合。它没有固定的大小。不像字符串,其大小是可变的,通过对偏移量进行赋值以及其他各种列表的方法进行调用,列表确实能够修改其大小。
1、序列操作
支持所有字符串所讨论过的序列操作。唯一的区别就是其结果往往是列表而不是字符串。所有长度,索引,切片等操纵
>>> L=[123,'spam',1.23]
>>> len(L)
3
>>> L[0]
123
>>> L[-1]
1.23
>>> L[:]
[123, 'spam', 1.23]
>>> L[1:]
['spam', 1.23]
>>> L[:2]
[123, 'spam']
>>> L*2
[123, 'spam', 1.23, 123, 'spam', 1.23]
>>> L+[4,5,6]
[123, 'spam', 1.23, 4, 5, 6]
2、类型的特定操作
Python的列表与其他语句中的数组有些类似,但列表要强大的多。列表没有固定类型的约束。此外和字符串不同,列表能够按照需要增加或减小列表大小。
添加
>>> L.append('NI')
>>> print L
[123, 'spam', 1.23, 'NI']
删除
>>> L.pop(2)
1.23
>>> L
[123, 'spam', 'NI']
插入
>>> L.insert(0,'test')
移除
>>> L.remove(123)
排序
>>> L.sort() 默认安装升序进行排序
排序翻转
>>> L.reverse()
3、边界检查
尽管列表没有固定的大小,Python仍不容许引用不存在的元素。
>>> L
['NI', 'spam', 'test']
>>> L[99]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> L[99]=1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
为了让一个列表增大需要调用append这样的列表方法
4、嵌套
Python核心数据类型的一个优秀特性就是它们支持任意的嵌套,能够以任意的组合对其进行嵌套。并可以深层次的嵌套都可以(比如,能投让一个列表包含一个字典,并在这个字典中包含另外一个列表等)。这种特性的一个直接的应用就是实现矩阵、或者Python中的“多维数组”。一个嵌套列表的列表能够完成这个基本操作。
>>> M=[[1,2,3],
... [4,5,6],
... [7,8,8]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 8]]
获取元素
>>> M[1]
[4, 5, 6]
>>> M[1][2]
6
获取了第二行第三个元素
5、列表解析
处理寻的操作和列表的方法中,Python还包含了一个更高级的操作。称作列表解析表达式,从而提高了一种处理像矩阵这样结构的强大工具
>>> col2=[row[1] for row in M]
>>> col2
[2, 5, 8]
更复杂一点的
>>> [row[1]+1 for row in M]
[3, 6, 9]
>>> [row[1] for row in M if row[1]%2==0]
[2, 8]
>>> [c*2 for c in 'spam']
['ss', 'pp', 'aa', 'mm']
六、字典
Python中的字典不是序列,而是一种映射。映射是一个其他对象的集合,但是她们是通过键而不是位置来存储的。实际上,映射并没有任何可靠的从左至右的顺序。它们简单地将键映射为值。字典是python核心对象集合中唯一一种映射类型。也具有可变性-可以改变,并可以随需求增加或减少,就像列表那样。
1、映射操作
作为常量编写时,字典编写在大括号中,并包含了一系列的“键:值”对。在我们需要将键和一系列值相关联时(如描述某事务的某属性)字典很有用。
>>> D={'food':'spam','quantity':4,'color':'pink'}
字典可以通过键对这个字典进行索引来读取或改变键所关联的值。字典的索引操作使用的语法和序列相同,但在方括号中的元素是键,而不是相对位置
>>> D
{'food': 'spam', 'color': 'pink', 'quantity': 4}
>>> D['food']
'spam'
>>> D['quantity']+1
5
除了使用大括号这种常量形式,还可以一下不同的创建字典的方法
>>> D={}
>>> D['name']='diege'
>>> D['job']='op'
>>> D['age']='28'
>>> D
{'age': '28', 'job': 'op', 'name': 'diege'}
>>> D['name']
'diege'
>>> print D['name']
diege
2、重访嵌套
更复杂一点字典。比如记录名和姓,多个工作头衔。产生了python对象嵌套的应用
>>> off={'name':{'first':'wang','last':'diege'},'job'['dev','mgr'],'age':28}
>>> off
{'age': 28, 'job': ['dev', 'mgr'], 'name': {'last': 'diege', 'first': 'wang'}}
顶层三个键
两个字典嵌套的读取
>>> off['name']
{'last': 'diege', 'first': 'wang'}
>>> off['name']['last']
'diege'
字典嵌套列表的读取
>>> off['job']
['dev', 'mgr']
>>> off['job'][1]
'mgr'
>>> off['job'][0]
'dev'
为嵌套添加数据
>>> off['job'].append('jantior')
>>> off['job']
['dev', 'mgr', 'jantior']
>>> off['job'][2]
'jantior'
>>> off
{'age': 28, 'job': ['dev', 'mgr', 'jantior'], 'name': {'last': 'diege', 'first': 'wang'}}
在底层语言中不要改对象时,必须小心地区释放掉所有对象空间。在python中,当最后一次引用对象后,这个对象所有占用的内存空间将自动清理掉
>>> off=0
从技术上说。python具有一种所谓垃圾收集的特性,在程序运行时可以清理不再使用的内存。从而从管理代码中这样的细节中解放出来,在pyton中,一旦一个对象的最后一次饮用被移除,空间将会理解收回。
3、键的排序:for循环
作为映射,字典进支持通过键获取元素。通过调用方法,他们也支持类型特定的操作。字典中没有顺序,那么我们需要强调一个顺序时,如何办?
可以通过最新的sorted内置函数(sorted返回结果并对对象类型进行排序)。
>>> D={'a':1,'b':2,'c':3}
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> sorted(D)
['a', 'b', 'c']
>>> for key in sorted(D):
... print key,'=>',D[key]
...
a => 1
b => 2
c => 3
for循环是一个遍历一个序列中所有元素并按顺序对每一元素运行一些代码简单有效的方法。
for循环及与其作用相近的while循环,是在脚本中编写重复性任务语句的主要方法
也可以用在字符串中
>>> for c in 'diege':
... print c
...
d
i
e
g
e
4、迭代和优化
>>> squ=[x**2 for x in [1,2,3,4,5]]
>>> squ
[1, 4, 9, 16, 25]
能够编写一个等效的for循环,通过在运行时手动增加列表来创建最终的列表
>>> squ=[]
>>> for x in [1,2,3,4,5]:
... squ.append(x**2)
...
>>> squ
[1, 4, 9, 16, 25]
pyhon一个主要的原则是:首先为了简单和可读性去编写代码。在程序运行后,并证明了确实有必要考虑性能后,再考虑该问题。更多情况是代码本身就已足够快了。如果需要提高代码的性能。那么python提供time,以及timeit模块和profile模块,用于测试运行时间.
5、不存在的键:if测试
尽管我们能通过给新的键赋值来扩展字典,但是获取一个不存在的键值仍然是一个错误。避免获取到一个不存在的键我们使用字典的has_key方法判断键的存在性
>>> D['k']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'k'
>>> help(D.has_key)
Help on built-in function has_key:
has_key(...)
D.has_key(k) -> True if D has a key k, else False
>>> D.has_key('k')
False
>>> if not D.has_key('f'):
... print 'missing'
...
missing
测试的结果是真的话j将运行一些代码。if是python的主要选择工具。完整语法为if elif else
还有其他的方法创建字典并避免取不存在的字典键(包括get方法,成员表达式,以及try语句)
七、元组
元组对象(toople或tuhple)基本就像一个不可改变的列表。像列表一样,元组是有序列,但是它具有不可变性,和字符串类似。
元组是不可改变的列表
字符串 元组 不可能改变
列表 字典 可以改变
字符串 元素 列表 有三x
列表具有的特性员组都具有,如果长度,切片等
>>> T=(1,2,3,4)
>>> len(T)
4
>>> T[:]
(1, 2, 3, 4)
>>> T[1]
2
>>> T[-1]
4
1、为什么要用元组
元组在实际中通常并不想列表那样常用,但是它的关键是不可变性。如果在程序中以列表的形式传递一个对象的结合,它能够在任何地方改变;如果使用元组的话,则不能。也就是说,元组提供了一种完整性的约束。对编写大程序有用。
八、文件
文件对象是python代码对电脑上外部文件的主要接口。虽然文件是核心类型,但是它有些特殊:没有特定的常量语法创建文件。需要调用内置open函数创建一个文件对象,以字符串的格式传递给它一个外部的文件名以及一个处理模式的字符串。
1、写入
>>> f=open('data.txt','w')
>>> f.write('Hello\n')
>>> f.write('world\n')
>>> f.close()
默认文件保存在运行python的起始路径
需要保存在其他路径需要在创建时指定
>>> f=open('/usr/python.txt','w')
>>> f.write('dir test for ptyhon!\n')
>>> f.close()
ofreebsd# cat /usr/python.txt
dir test for ptyhon!
2、读取
>>> f=open('data.ext','r')
默认为r,如果没有指定默认为r
>>> f.read()
'Hello\nworld\n'
这样打印出来不适合
>>> frd=f.read()
>>> print frd
Hello
world
3、按行读取
>>> f=open('data.ext','r')
>>> f.readline() 每次读取一行
'Hello\n
在读取剩下行
>>> f.readlines()
['world\n']
读取所有行
>>> f=open('data.ext','r')
>>> f.readlines()
['Hello\n', 'world\n']
和f.read()类似
>>> f=open('/etc/hosts','r')
>>> hosts=f.read()
>>> hosts.split()
['::1', 'localhost', 'localhost.skylog.cn', '127.0.0.1', 'localhost', 'localhost.skylog.cn', '192.168.1.200', 'ofreebsd.skylog.cn', '192.168.1.110', 'client01.skylog.cn', '192.168.1.250', 'client05.skylog.cn']
换行符拆分
>>> hosts.split('\n')
['192.168.1.110 client01.skylog.cn', '192.168.1.250 client05.skylog.cn', '']
file文件数据类型的变量名称
dir(file)
如'mode'权限属性
4、其他文件类工具
pipes,fifos,sockets,keyed-access files,对象持久,基于描述符的文件,关系数据库和面向对象数据库接口等
九、其他核心类型
集合是最近增加到这门语言中的类型。集合是通过调用内置set函数而创建的对象的容器,它支持一般的数学集合操作
>>> X=set('spam')
>>> Y=set(['h','a','m'])
>>> X,Y
(set(['a', 'p', 's', 'm']), set(['a', 'h', 'm']))
>>> X&Y #求同
set(['a', 'm'])
>>> X|Y #联合
set(['a', 'p', 's', 'h', 'm'])
>>> X-Y #求异
set(['p', 's'])
也添加了十进制数(固定精度浮点数)和布尔值(预定义的true和false),以及长期以来一直支持的特殊占位符对象NONE
对象的类型判断
>>> type(L)
<type 'list'>
>>> type(L)==type([])
True
>>> type(L)==list
True
>>> if isinstance(L,list):
... print 'yes'
...
yes
在python程序这样做是错误的。在代码中检验特定的类型,实际上破坏了它的灵活性。没有代码检查,代码也许能使用整个范围的类型
十、用户定义的类
>>> class Worker:
... def __init__(self,name,pay):
... self.name=name
... self.pay=pay
... def lastName(self):
... return self.name.split()[-1]
... def giveRaise(self,percent):
... self.pay*=(1.0+percent)
这个类定义了一个新的对象种类,有name和pay两个属性。也有两个小的行为编写为函数的形式。就像函数那样去调用类,会生成我们新类型的一个实例并且类的方法调用时,类的方法自动获取被处理的实例(其中的self参数)
>>> bob=Worker('Bob Smith',50000)
>>> bob=Worker('Sue Jones',60000)
>>> bob.lastName()
'Jones'
>>> bob=Worker('Bob Smith',50000)
>>> sue=Worker('Sue Jones',60000)
>>> bob.lastName()
'Smith'
>>> sue.giveRaise()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: giveRaise() takes exactly 2 arguments (1 given)
>>> sue.giveRaise(.10)
>>> sue.pay
66000.0
采用的“self" 对象是我们把这个叫做面向对象模型的原因,即一个类中的函数总有一个隐含的对象。一般来说,尽管这样,基于类的类型是建立在并使用了核心类型的。例如,这里的一个用户定义的Worker对象,是一个字符串和数字的集合,附加了用来处理这两个内置对象的函数。