一、Python对象
所有Python对象都拥有三个特性:
身份:每个对象都有一个唯一的身份标识自己,任何对象的身份可以通过id() 来得到,这个值可以被认为是该对象的内存地址。
类型:对象的类型决定了该对象可以保存什么类型的值。可以使用type() 来查看对象的类型。
值 :对象表示的数据项。
对象属性
某些Python对象有属性、值或相关联的可执行代码,比如方法。Python使用句点标记法来访问属性。最常用的属性是函数和方法,不过有一些Python类型也有数据属性。
二、标准类型
也称作“基本数据类型”
- 数字(分子类型,其中三个是整型)
- Integer 整型
- Boolean 布尔型
- Long integer 长整型
- Floating point real number 浮点型
- Complex number 复数型
- String 字符串
- List 列表
- Tuple 元组
- Dictinary 字典
三、其他内建类型
- 类型
- Null对象(None)
- 文件
- 集合/固定集合
- 函数/方法
- 模块
- 类
3.1 类型对象和type类型对象
类型是保存对象的一些固有行为和特性。
>>> type(10)
>>> type(type(10))
所有类型对象的类都是type, 它也是所有Python类型的根和所有Python标准类的默认元类。
3.2 None —— Python的Null对象
特殊类型Null对象,它只有一个值,就是None。不支持任何运算也没有内建方法。None没有什么有用的属性,它的布尔值总是False。
布尔值:
空对象、值为零的任何数字或Null对象None的布尔值都是False。比如:0 0.0 0L "" [] () {}
四、内部类型
4.1 代码对象
代码对象是编译过的Python源代码片段,它是可执行对象。可以通过内建函数compile() 得到代码对象。代码对象可被exec命令或 eval() 内建函数来执行。
代码对象本身不包含任何执行环境信息,它是用户自定义函数的核心,在被执行时动态获得上下文。事实上代码对象是函数的一个属性,除此之外,函数还有其他属性:函数名、文档字符串、默认参数、全局命名空间等。
4.2 帧对象
帧对象包含Python解释器在运行时所需要知道的所有信息。它的属性包括指向上一帧的链接,正在被执行的代码对象,本地及全局名称空间字典及当前指令等。每次函数调用产生一个新的帧,每一个帧对象都会相应的创建一个C栈帧。用到帧对象的一个地方是跟踪记录对象。
4.3 跟踪记录对象
当代码出错,Python会引发一个异常。若异常未被捕获和处理,解释器就会推出脚本,并打印诊断信息。当异常发生时,一个包含针对异常的栈跟踪信息的跟踪记录对象被创建。若异常有自己的处理程序,处理程序就会访问这个跟踪记录对象。
4.4 切片对象
当使用Python扩展的切片语法时,就会创建切片对象。切片对象也可以由内建函数 slice() 来生成。
>>> str = 'abcde'
>>> str[::-1]
'edcba'
>>> str[::-2]
'eca'
>>> l = [123, 456, 'asdf', 'qwer']
>>> l[::-1]
['qwer', 'asdf', 456, 123]
4.5 省略对象
用于扩展切片语法中,起记号作用。这个对象在切片语法中表示省略号。类似Null对象None,省略对象有一个唯一的名字Ellipsis ,它的布尔值始终为True。
4.6 Xrange对象
调用内建函数xrange() 会生成一个Xrange对象,用于需要节省内存使用或range() 无法完成的超大数据集场合。
五、标准类型操作符
5.1 对象值的比较
比较操作符用来判断同类型对象是否相等,所有的内建类型均支持比较运算,比较运算返回值是布尔值。
5.2 对象身份比较
Python提供了 is 和 is not 操作符来测试两个变量是否指向同一个对象。
>>> l is str
False
>>> k = l
>>> l is k
True
>>> id(l)
139848006103408
>>> id(k)
139848006103408
Python中整型和字符串对象是不可变对象。
>>> a = 1
>>> id(a)
9105752
>>> b = 1
>>> id(b)
9105752
>>> c = 1.0
>>> id(c)
13506488
>>> d = 1.0
>>> id(d)
11071344
Python仅缓存简单整型,缓存的整型范围是(-5, 256) Python 2.7.11
5.3 布尔类型
布尔逻辑操作符 and or not 都是Python关键字。not 拥有最高优先级,只比所有比较操作符低一级,and 低于 not , or 低于 and。
六、标准类型内建函数
6.1 type()
type() 接受一个对象作为参数,并返回它的类型。它的返回值是一个类型对象。
>>> type(10)
>>> type(type(10))
6.2 cmp()
cmp()用于比较两个对象。如果obj1 小于 obj2, 则返回一个负整型,反之则返回一个正整型, 若相等则返回0.
>>> a, b = 4, 12
>>> cmp(a,b)
-1
>>> cmp(b,a)
1
>>> b = 4
>>> cmp(a,b)
0
>>> a, b = 'abc', 'xyz'
>>> cmp(a,b)
-1
>>> cmp(b,a)
1
>>> b = 'abc'
>>> cmp(a,b)
0
6.3 str()和 repr()(以及 ` ` `操作符)
str() 和 repr()或 反引号操作符可以方便地以字符串的方式获取对象的内容、类型、数值属性等信息。str()获得的字符串可读性好,而repr()获得的字符串通常可用于重新获得该对象,例如 obj == eval(repr(obj)) 这个等式是成立的。
>>> str(1)
'1'
>>> str(2e10)
'20000000000.0'
>>> repr([1, 2, 3, 4, 5])
'[1, 2, 3, 4, 5]'
>>> `[1, 2, 3, 4, 5]`
'[1, 2, 3, 4, 5]'
并不是所有repr()返回的字符串能够用 eval() 内建函数得到原来的对象。
6.4 type() 和 isinstance()
#!/usr/bin/python
# -*- coding:utf-8 -*-
def displayNumType(num):
print num, 'is',
if isinstance(num, (int, long, float, complex)):
print 'a number of type:', type(num).__name__
else:
print 'not a number at all!!!'
displayNumType(-69)
displayNumType(99999999999999999999)
displayNumType(98.6)
displayNumType(-5.2+1.8j)
displayNumType('xxx')
输出
-69 is a number of type: int
99999999999999999999 is a number of type: long
98.6 is a number of type: float
(-5.2+1.8j) is a number of type: complex
xxx is not a number at all!!!
例子进阶:
#!/usr/bin/python
# -*- coding:utf-8 -*-
def displayNumType(num):
print num, 'is',
if type(num) == type(0):
print 'an integer'
elif type(num) == type(0L):
print 'a long'
elif type(num) == type(0.0):
print 'a float'
elif type(num) == type(0+0j):
print 'a complex number'
else:
print 'not a number at all!!!'
displayNumType(-69)
displayNumType(99999999999999999999)
displayNumType(98.6)
displayNumType(-5.2+1.8j)
displayNumType('xxx')
这里我们看到代码中,调用了两次type(). 利用types模块,我们可以将检测到的类型与一个已知类型进行比较,从而减少函数调用次数,提高代码的性能。
>>> import types
>>> types.IntType
对象值比较VS对象身份比较
在运行事情,只有一个类型对象来表示整型类型,也就是说,type(0),type(10),都是同一个对象
。既然他们是同一个对象,我们就可以用对象身份比较来替代对象值比较。如果对象是不同的,那意味着原来的变量一定是不同类型的。我们就没必要去检查(值)了。
>>> if type(num) is types.IntType
减少查询次数
>>> if type(num) is IntType
isinstance()是个布尔函数,接受一个或多个对象作为参数,由于类型和类现在都是一回事,int 现在既是一个类型,又是一个类。我们可以使用isinstance()函数来让if 语句更方便。
if isinstance(num, int)....
所以脚本最终使用了 isinstance()函数,而且接受一个类型对象的元组作为参数,这样我们就不必写大量的 if-elif-else了。
七、类型工厂函数
Python2.2 统一了类型和类,原来的所谓内建转换函数 int() type() list() 等现在成了工厂函数,实际上它们是类,调用时,实际上是生成了该类型的一个实例。
八、标准类型的分类
8.1 存储模型
根据这种类型的对象能保存多少个对象,将其分为原子(标量)存储 和 容器存储。所有的Python容器对象都能容纳不同类型的对象。
类型分类
|
|
分类 |
Python类型 |
标量/原子类型 |
数值(所有的数值类型),字符串(全部是文字) |
容器类型 |
列表、元组、字典 |
8.2 更新模型
按更新模型的类型分类
分类 |
Python类型 |
可变类型 |
列表,字典 |
不可变类型 |
数字、字符串、元组 |
>>> x = 'a'
>>> id(x)
140622681425080
>>> x = 'b'
>>> id(x)
140622681425120
>>> i = 1
>>> id(i)
38740312
>>> i += 1
>>> id(i)
38740288
>>> l = [1, 2, 3, 4]
>>> id(l)
140622476628624
>>> l[0] = 10
>>> id(l)
140622476628624
8.3 访问模型
根据访问我们存储的数据的方式对数据类型进行分类。访问模型中有三种访问方式:直接存取、顺序和映射。
对于非容器类型可以直接访问,所有的数值类型归到这类里。
序列类型是指容器内的元素从0开始的索引顺序访问。字符串、列表和元组归到这类里。
映射类型类似于序列类型。但是它的索引并不适用顺序的数字偏移量取值,它的元素无序存放,通过唯一的键来访问。
访问模型来分类
分类 |
Python类型 |
直接访问 |
数字 |
顺序访问 |
字符串,列表,元组 |
映射访问 |
字典 |
标准类型分类
数据类型 |
存储模型 |
更新模型 |
访问模型 |
数字 |
标量 |
不可更改 |
直接访问 |
字符串 |
标量 |
不可更改 |
顺序访问 |
列表 |
容器 |
可更改 |
顺序访问 |
元组 |
容器 |
不可更改 |
顺序访问 |
字典 |
容器 |
可更改 |
映射访问 |