Python对象的基本概念
对象是Python中最基本概念。Python程序可以分解成模块、语句、表达式、以及对象
- 程序由模块构成
- 模块包含语句
- 语句包含表达式
- 表达式建立并处理对象
Python内置类型
Python的核心数据类型
- 数字 1234
- 字符串 'sad'
- 列表 [1,[2,'three'],4]
- 字典 ['food':'spam']
- 元组 (1,‘aaa’,'43')
- 文件 open('filename','r')
- 集合 set('abc')
- 其他类型 None,布尔类型
- 编程单元类型 函数 模块 类
- 与实现相关的类型 编译的代码堆栈跟踪
Python中的类型特点
- Python中并没有类型声明,运行的表达式的语法决定了创建和使用的对象的类型
- Python是动态类型的,它会自动地跟踪你的类型而不是要求声明代码
- Python也是强类型语言,只能对一个对象进行适合该类型的有效操作
Python数据类型——数字
- Python中数字包括:整数、浮点数等(复数、进制数)、固定精度的十进制数、有理分数、集合、布尔类型、无穷的整数精度、各种数字内置函数和模块
数字常量
基本类型中,Python提供了:整数(正整数和负整数)和浮点数(带有小数部分的数字)
在Python2.6中 整数分为:
- 一般整数(32位)
- 长整数(无穷精度)
当整数的值超过32位时会自动转换为长整数。当需要额外的精度的时候,Python会自动地转换为长整数
在Python3.0中 整数是一个单独的类型
Python3.0中,一般整数和长整数已经合二为一了,只有整数这一种。在Python3中整数在程序中不会再用末尾的l或L表示。
十六进制数、八进制和二进制常量
整数可以编写为十进制(以10为基数)、十六进制(以16为基数)、八进制(以8为基数)和二进制(以2为技术)。
- 十六进制以0x或0X开头,后面接十六进制的数字09和AF
- 八进制常量以数字0o或00开头,后面接着数字0~7构成的字符串
- 二进制常量 以0b或0B开头,后面跟着二进制数字0~1
处理进制转换的函数: - oct():会将十进制数转换为八进制数
- hex():函数会将十进制转换为十六进制
- bin():会将十进制转换为二进制
- 内置的Int函数会将一个数字的字符串变换为一个整数,并可以通过定义的第二个参数来确定变换后的数字的进制
int('0x40',16)
int('0b1000000',2)
- 使用eval函数 可以把字符串作为Python的代码
eval('0o100')
复数
Python的复数常量协程实部+虚部的写法,虚部是以j或J结尾。实部可有可无,
小数数字 decimal
Python2.4介绍了一种新的核心数据类型:小数对象,小数是通过一个导入的模块调用函数后创建的,而不是通过运行常量表达式创建的。小数对象就像浮点数。小数有固定的位数和小数点。小数是有固定的精度的浮点值。
- 看下面的情况
0.1+0.1+0.1-0.3 这样的结果应该为0 ,但是在Python中运行结果却不是0 而是接近于0
5.551115123125783e-17
如果使用小数对象来进行准确计算的话:
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3'))
>>> 0.0
decimal模块中的其他工具可以设置所有小数数值的精度、设置错误处理等
import decimal
print(decimal.Decimal(1) / decimal.Decimal(7))
# 设定小数数值精度
在Python2.6之后的版本中,可使用上下文管理器语句来重新设置临时精度,在语句退出后,精度又重新设置为初始值:
decimal.getcontext().prec = 3
print(decimal.Decimal(1) / decimal.Decimal(7))
>>> 0.1428571428571428571428571429
0.143
分数类型
Python2.6和Python3.0引入了分数类型,实现了有理数对象,明确保留了一个分子和一个分母
分数的模块为 fractions
# 分数模块
from fractions import Fraction
x = Fraction(1, 3)
y = Fraction(4, 6)
# 通过浮点数来运算
Fraction('.25')
Fraction('1.25')
print(x)
print(y)
>>> 1/3
>>> 2/3
创建分数后,可以进行分数的计算
print(x + y)
print(x - y)
处理数字对象的工具
表达式操作符
- 加法
- 乘法
- **乘方
- / 除法
* 传统除法和真除法 这个操作对于整数会省去小数部分,在Python3.0后无论任何类型都会保持小数部分 - // floor除法 这个操作不考虑操作对象的类型,总会省略掉结果的小数部分,剩下最小的能整除的整数部分
对于在Python2.x和Python3.0中,如果程序依赖于截断整数除法,在Python中都使用//。//把结果向下截断到它的下层,真正结果之下的最近整数。但其直接效果是向下舍入,并不是严格截断。对于负数来说会出现 5/-2=-3的情况 - >> << 移位运算
内置数学函数
pow、abs、round、int、hex、bin
import math
print(math.pi, math.e)
# sin
print(math.sin(2 * math.pi / 180))
# 平方根
print(math.sqrt(144))
# 计算冪
print(pow(3, 4))
# 绝对值
print(abs(-25))
# 求和
print(sum((1, 2, 3, 4, 2, 2, 1)))
# 查找最大值
print(max((3, 4, 5, 6, 1, 9)))
# 查找最小值
print(min((1, 3, 5, 4, 9, 8)))
# 截断
print(math.floor(2.6)) >>>2
# 取舍
print(round(2.6)) >>>3
# 真除
print(math.trunc(2.3333))
## Python计算平方根
math.sprt(144)
144** 0.5
pow(144,.5) 内置方法
- random
标准库中的random模块,可以选出在0和1之间的任意浮点数、选择在两个数字之间的任意整数、在一个序列中任意挑选一项
print(random.random()) # 在0-1中选择任意浮点数
print(random.randint(1, 10)) # 选择两个数字之间的任意整数
print(random.choice(['a', 'b', 'c'])) # 在一个序列中任意挑选一项
公用模块
random、math
混合操作操作符优先级
括号分组的子表达式优先级要大于二级运算
二级运算大于一级运算
混合类型自动升级
对于 40+3.14这类的混合运算,在Python中就涉及到数字类型的复杂度:整数比浮点数简单,浮点数比复数简单。当一个整数与浮点数混合时。整数首先会升级转为浮点数的值,之后通过浮点数的运算法则得到浮点数的结果。对于任何混合类型的表达式,其中一个操作对象是更为复杂的数字,则会导致其他的操作对象升级为一个复杂的数字。使得表达式获得一个复杂数字类型的结果
Python不会在其他的类型之间进行转换,一个字符串和一个整数相加,就会产生错误。在Python2.6中非数字混合类型也可以比较,但是不会执行转换。在Python3.0中,非数字混合类型的比较是不允许的
数字的模块
- math模块
math模块包括更高级的数学工具
Python数据类型——字符串
字符串在Python中作为序列,是一个包含其他对象的有序集合,字符串是单个字符的字符串序列
字符串序列操作
- 支持各个元素包含位置顺序的操作
* 索引按照从最前面的偏移量进行编码:从0开始,第一项索引为0 第二项为1。。。 - 反向索引
* 在Python中,我们能够反向索引,从最后一个开始。
S[-1] 等效于 S[len(S)-1]
- 分片操作
分片的一般形式为X[I:J]: 表示取出在X中从偏移量为I,直到但不包括偏移量为J的内容 - 合并操作
作为一个序列,字符串也支持使用加号进行合并,使用加号将两个字符串合并成一个新的字符串。货值金额重复(通过重复一次创建一个新的字符串) - + 加号对不同对象有不同的意义:对于数字为加法,对于字符串为合并。
- Python允许字符串包括在单引号或双引号、三个引号中。
- Python也支持原始字符串常量 不含有反斜线等转移机制,这样的字符串常量是以字母'r'开头的
字符串的不可变性
字符串在Python中具有不可变性——字符串在Python中创建后就不能呗改变。不能通过对某某一位置进行赋值而改变字符串。可以创建一个新的字符串并以同一个变量名对其进行赋值
在Python中的每一个对象都可以分为不可变性或者可变性。
在核心类型中,数字、字符串和元组是不可变的
列表和字典是可以自由的改变。
Python变量赋值
Python变量不需要提前声明,当给一个变量赋值的时候就创建了它。可能赋的是任何类型的对象,当变量出现一个表达式就会用其值替换。
在使用变量的值之前必须对其赋值
返回对象的所有属性 dir
- 可以调用内置的dir函数,将会返回一个列表。其中包含了对象的所有属性。由于方法是函数属性。所以函数也会在这个列表中出现
Python数据类型——布尔类型
Python中的布尔数据类型,叫做bool,其值为True和False,并且其值True和False是预先定义的内置的变量名。在内部,新的变量名True和False是bool的实例,实际上仅仅是内置的整数类型int的子类。True和False的行为和整数1和0是一样的。它们是作为关键字True和False显示的,而不是数字1和0
Python数据类型——列表
列表是一个任意类型的对象的位置相关的有序集合。列表没有固定的大小。
列表的序列操作
列表是序列的一种,列表支持所有的我们对字符串所讨论过的序列操作
- 计算列表长度
len(L)
3
- 切片操作
L[:-1]
[123, 'span']
- 拼接字符串形成一个新的字符串
>>> L+[1,3,4,5,6]
[123, 'span', 1.2345, 1, 3, 4, 5, 6]
>>> L
[123, 'span', 1.2345]
类型的特定操作
Python的列表与其他语言中的数组有些类似,但列表更加强大。列表没有固定类型的约束。
- 拼接元素 append方法扩充了列表的大小并在列表的尾部插入一项
>>> L.append('hello')
>>> L
[123, 'span', 1.2345, 'hello']
- 移除给定偏移量的一项pop
>>> L.pop(2)
1.2345
>>> L
[123, 'span', 'hello']
* sort 按照升序对列表进行排序
* reverse对列表进行翻转
边界检查
列表没有固定大小,Python不允许引用不存在的元素。超出列表末尾之外的索引会导致错误
>>> L[99]
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
L[99]
IndexError: list index out of range
>>> L[99]=1
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
L[99]=1
IndexError: list assignment index out of range
嵌套
Python的核心数据类型支持任意嵌套。能够以任意的组合进行嵌套
>>> M = [[1,2,3],[4,5,6],[7,8,9]]
>>> M[1]
[4, 5, 6]
列表解析
Python中还有更高级的列表操作,称作列表解析表达式
>>> col2 = [row[1] for row in M]
>>> col2
[2, 5, 8]
列表解析表达式通过对序列中的每一项运行一个表达式来创建一个新列表的方法,每次一个,从左至右。列表解析表达式是编写在方括号中的,上面的语句的意思是:把矩阵M的每个row中的row[1]放在一个新的列表中
分析一下,上面的列表表达式 会使用for循环开始循环M,先循环出来的是1,2,3 然后将索引1放到新的列表中,再执行下一次循环 456 取出索引为1 再执行下一次循环 789取出索引为1 所以最终得到的列表为[2,5,8]
在最近的Python版本中,括号中的解析语法可以用来创建产生所需结果的生成器
G = (sum(row) for row in M)
>>> next(G)
>>> 6
>>> next(G)
>>> 15
Python数据类型——集合
Python2.4引入了一种新的类型 集合(set),这是一些唯一的、不可变的对象的一个无序集合
- 一个项在集合中只能出现一次,不管添加了多少次
- 集合只能包含不可变的对象类型,列表和字典不能嵌入到集合中,元组由于不可变所以可以嵌入
- 集合具有列表和字典有共同的行为
- 集合是可以迭代的
- 集合既不是序列也不是映射类型,是自成一体的类型。集合本质上具有基本的数学特性
集合常量
在Python2.x中我们使用set()来创建一个集合。在3.0中我们创建集合使用内置函数来创建集合对象
set('1234')
{1,2,3,4}
在Python中 {}是一个字典,所以空的集合必须通过内置函数set来创建
Python3.0中的集合解析
Python3,0还引入了一个集合解析构造,类似于列表解析的形式。集合的解析编写在花括号中。集合解析运行一个循环并在每次迭代时收集一个表达式的结果,通过一个循环变量来访问当前的迭代值以用于集合表达式中。
print({x ** 2 for x in [1, 2, 3, 4]})
在上面这个集合解析表达式中,循环的部分写在表达式的右边,而集合表达式编写在左边。这个集合解析式的含义:对于列表中的每一个元素x,给出包含x的平方的一个新的集合
再来看一个栗子:集合解析也可以迭代其他类型的对象,例如:字符串
print({x for x in 'hello world'})
>>> {'r', 'h', ' ', 'd', 'w', 'o', 'l', 'e'}
print({c * 4 for c in 'hello'})
>>> {'hhhh', 'eeee', 'oooo', 'llll'}
集合的用途
集合由于每项在集合中只能存在集合中存储一次,集合可以用来把重复项从其他集合中过滤掉。直接把集合转换为一个集合
L = [1, 2, 1, 3, 2, 4, 5]
s1 = set(L)
print(s1)
L = list(s1)
print(L)
Python数据类型——字典
Python中的字典:不是序列,而是一种映射。映射是一个其他对象的集合。通过键而不是通过相对位置来存储的。映射并没有任何可靠的顺序。
字典是Python核心对象集合中的唯一的一种映射类型,具有可变性。可以随需求增大或减小
映射操作
字典编写在大括号中,并包含一系列的“键:值”对。我们可以通过键对这个字典进行索引来读取或改变键所关联的值。字典的索引操作使用的是和序列相同的语法,只不过在方括号中使用的是键,而不是相对位置
>>> D = {'food':'Spam','quantity':4,'color':'pink'}
>>> D['food']
'Spam'
>>> D['quantity']+=1
>>> D
{'food': 'Spam', 'quantity': 5, 'color': 'pink'}
字典的操作
键的排序
字典不是序列,并不包含任何可靠的顺序。如果我们确实需要某种顺序的时候,我们常用的方法就是通过字典的key收集一个键的列表,然后使用列表sort方法进行排序。然后使用Python的for循环逐个进行显示
>>> Ks = list(D.keys())
>>> Ks
['food', 'quantity', 'color']
对键的列表进行排序
>>> Ks.sort()
>>> ks
['color', 'food', 'quantity']
按照排序后的键来显示字典的元素
>>> for key in Ks:
print(key,'->',D[key])
color -> pink
food -> Spam
quantity -> 5
判断键是否存在 if测试
尽管我们能够通过给新的键赋值来扩展字典,但是获取一个不存在的键值仍然是一个错误
但是在某些情况下我们并不是总知道当前的字典中存在什么键,我们就需要先测试键是否存在。
in关系表达式允许我们查询字典中一个键是否存在。并可以使用if进行判断
>>> 'food' in D
True
>>> 'foot' in D
False
Python数据类型——元组
元组tuple就像一个不可以改变的列表。就像列表一样,元组是序列,但是它具有不可变性。和字符串类似,元组编写在圆括号中而不是方括号中。支持任意类型,任意嵌套
T = (1, 2, 3, 54,3)
print(len(T))
API
- index(value) 返回value在元组中对应的索引
- count(value) 返回对应的value出现的次数
print(T.count(3))
>>> 2
元组类型的混合嵌套
TA = ('spam', 3.0, [11, 22, 33])
print(TA[0])
print(TA[2][2])
>>> spam
>>> 33
元组的长度不可以增长或缩短,因为元组是不可变的
···
TA.append(33)
会报AttributeError错误
···
Python数据类型——文件
文件对象是Python代码对电脑上外部文件的主要接口。没有特定的常量语法创建文件。要创建一个文件对象,需要调用内置的open函数以字符串的形式传递给它一个外部的文件名以及一个处理模式的字符串。
- 在当前文件夹下创建文件,并向它写入文本。
f = open('test.txt', 'w')
f.write('Hello\n')
f.write('world\n')
f.close()
- 再读出写入的文件内容
f = open('test.txt', 'r')
text = f.read()
print(text)
tips:Python读取一个文件的最佳方式是不读它,文件提供了一个迭代器。我们可以使用迭代器来进行读取
其他核心类型
Python其他的数值类型:十进制数、分数、布尔值、None(特殊的占位符对象)