Python学习手册笔记(四)介绍Python对象类型
在Python中,数据以对象的形式出现——无论是Python提供的内置对象,还是使用Python或是像C扩展库这样的扩展语言工具创建的对象。对象无非是内存中的一部分,包含数值和相关操作的集合。
Python程序可以分解成模块、语句、表达式以及对象,如下所示
1.程序由模块构成
2.模块包含语句
3.语句包含表达式
4.表达式建立并处理对象
1为什么使用内置类型
使用底层语言C或C++,要花很大一部分工作集中于用对象(或者叫数据结构)去表现应用领域的组件。需要部署内存结构、管理内存分配、实现搜索和读取例程等工作。这些工作听起来乏味,容易出错,而且往往背离程序的真正目标。
Python提供了强大的对象类型作为语言的组成部分,事实上,除非有内置类型无法提供的特殊对象要处理,最好总是使用内置对象而不是使用自己的实现。下面是原因
l内置对象使程序更容易编写。内置对象往往能够表现问题领域的所有结构,仅适用内置对象就能够完成很多工作。
l内置对象是扩展的组件。人工实现的对象往往建立在像列表和字典这样的内置类型的基础上。
l内置对象往往比定制的数据结构更有效率。在速度方面,Python的内置对象类型优化了用C实现数据结构算法。
l内置对象是语言的标准的一部分。Python的内置工具是标准的,它们一般都是一致的,另一方面,独创的框架则在不同的环境都有所不同。
2Python的核心数据类型
内置对象
对象类型
例子
常量/创建
数字
1234,3.1415,3+4j,Decimal,Fraction
字符串
‘spam’, “guido’s”,
b’a\xolc’
列表
[1, [2,
‘three’],4]
字典
{‘food’:’spam’,
‘taste’:’yum’}
元组
(1, ‘spam’, 4,
‘U’)
文件
myfile = open(‘eggs’,
‘r’)
集合
set(‘abc’), {‘a’, ‘b’,
‘c’}
其他类型
type、None、布尔型
编程单元类型
函数、模块、类
与实现相关的类型
编译的代码堆栈跟踪
表并非完整,因为在Python程序中处理的每样东西都是一种对象。表中的对象类型称作为核心数据类型,因为它们是在Python语言内部高效创建的。也就是说,有一些特定的语法可以生成它们。
同样重要的是,一旦创建了一个对象,它就和操作集合绑定了——只可以对字符串进行字符串相关的操作,对列表进行列表相关的操作。Python是动态类型的(它自动跟踪你的类型而不是要求声明代码),但是它也是强类型语言(你只能对一个对象进行适合该类型有效的操作)。
3数字
常规类型:整数、浮点数,以及更加少见的类型:有虚部的复数、固定精度的十进制数、带分子和分母的有理数以及集合等。
Python中的数字支持一般的数学运算,例如加法(+)、乘法(*)、乘方(**)等。
注意计算2 **
100的结果:当需要时,Python
3.0的整数类型会自动提供额外的精度,以用于较大的数值。
一旦接触浮点数,可能会遇到一些奇怪的事情(无缘无故多出一些小数点,但是在新的版本可能会自动解决),也可以使用print来解决
>>>3.1415
* 2 # repr: as code
6.283000000000004
>>>print(3.1415
* 2) # str: suer-friendly
6.283
第一种形式看做是对象的代码形式repr,第二种是它的用户友好形式str。当使用类时,这两者的区别将会体现出来。
除表达式外,和Python一起分发的还有一些常用的数学模块,模块只不过是我们导入以供使用的一些额外工具包。
>>>import
math
>>>math.pi
3.1415926535897931
>>>math.sqrt(85)
9.2195444572928871
Math模块包括更高级的数学工具,如函数,而random模块可以作为随机数字的生成器和随机选择器
>>>import
random
>>>random.random()
0.59268735266273953
>>>random.choice([1,
2, 3, 4])
1
Python还包括一些较为少见的数字对象,例如复数、固定精度十进制数、有理数、集合和布尔值,第三方开源扩展领域甚至包含了更多(矩阵和向量)。
4字符串
就像任意字符的集合一样,字符床是用来记录文本信息的。它们是在Python中作为序列(一个包含其他对象的有序集合)提到的第一个例子。序列中的元素包含了一个从左到右的顺序——序列中的元素根据它们的相对位置进行存储和读取。从严格意义上来说,字符串是单个字符的字符串的序列,其他类型的序列还包括列表和元组
4.1序列的操作
可以通过内置的len函数验证字符串长度,并通过索引操作得到各个元素
>>>
S= ‘Spam’
>>>len(S)
# Length
4
>>>S[0]
# The first item in S. indexing by zero-based
position
‘S’
在Python中,索引是按照最前面的偏移量进行编码的,即从0开始,第一项索引为0,第二项索引为1,以此类推。
Python变量不需要提前声明,当给一个变量赋值时就创建了它,可能赋的是任何类型的对象,并且当变量出现在一个表达式时,就会用其值替换它。在使用变量的值之前必须对其赋值。我们需要把一个对象赋给一个变量以便保存它供以后使用。
在Python,我们能够反向索引,从最后一个开始。
>>>S[-1]
# The last item from the end in S
‘m’
>>>S[-2]
# The second to last item from the
end
‘a’
一般来说,负的索引号会简单地与字符串的长度相加,因此,以下两个操作是等价的:
>>>S[-1]
>>>S[len(S)-1]
我们能够在方括号中使用任意表达式,而不仅仅是使用数字常量——只要Python需要一个值,我们可以使用一个常量、一个变量或者任意表达式。Python的语法在这方面是完全通用的。
除了简单地从位置进行索引,序列也支持一种所谓的分配(slice)操作,这是一种一步就能提取整个分片(slice)的方法。例如:
>>>
S
‘Spam’
>>>S[1:3]
‘pa’
一般形式为X[I:J],表示“去除在X中从偏移量为I,直到但不包括偏移量为J的内容”
在一个分片中,左边界默认为0,并且右边界默认为分片序列的长度。这引入了一些常用法的变体:
>>>S[1:]
‘pam’
>>>
S
‘Spam’
>>>S[0:3]
‘Spa’
>>>S[:-1]
‘Spa’
>>>S[:]
‘Spam’
最后,作为一个序列,字符串也支持使用加号进行合并(将两个字符串合成为一个新的字符串),或者重复(通过再重复一次创建一个新的字符串):
>>>
S
‘Spam’
>>>
S+ ‘xyz’ # Concatenation
‘Spamxyz’
>>>
S# S is unchanged
‘Spam’
>>>
S* 8 # Repetition
‘SpamSpamSpamSpamSpamSpamSpamSpam’
注意加号(+)对于不同的对象有不同的意义:对于数字为加法,对于字符串为合并。这是Python的一般特性:多态。简而言之,一个操作的意义取决于被操作的对象。这种多态的特性给Python代码带来了很大的简洁性和灵活性。由于类型并不受约束,Python编写的操作通常可以自动适用于不同类型的对象,只要它们支持一种兼容的借口(如同这里的+操作)。
4.2不可变性
每个字符串都被定义为生成的字符串作为结果,因为字符串在Python中具有不可变性——在创建后不能就地改变。但是你可以通过建立一个新的字符串并以同一个变量名对其进行赋值,因为Python在运行过程中会清理旧的对象
>>>
S
‘Spam’
>>>S[0]
= ‘z’ # Immutable objects cannot be
changed
…error
textomitted…
TypeError: ‘str’object does not support
item assignment
>>>
S= ‘z’ + S[1:] # But we can run
expre_ssions(表达式)
to make new objects
>>>
S
‘zpam’
在Python中的每一个对象都可以分为不可变性和可变性。在核心类型中,数字、字符串和元组是不可变的;列表和字典可变。在其他地方,这种不可变性可以用来保证在程序中保持一个对象固定不变。
4.3类型特定的方法
字符串还有独有的一些操作作为方法存在(对象的函数,将会通过一个调用表达式触发)。
例如,字符串的find方法是一个基本的子字符串查找的操作(它将返回一个传入子字符串的偏移量,或者没有找