读书笔记:Python 学习手册(1)
结于2021-07-28;
OREILY的书籍,可读性很强,入门类,而且这本书很厚;
- 第一部分 使用入门
- 第二部分 类型和运算
书前文
Python是一种简单的、解释型的、交互式的、可移植的、面向对象的超高级语言;
Python是一种很流行的开源编程语言,可以在各个领域中用于编写独立的程序和脚本;
Python3.0 清理了一些语言中长久的瑕疵,同时保留核心思想并添加一些新工具;
apply(f, ps, ks)
已删除,由f(*ps, **ks)
代替;D.has_key(K)
已删除,由K in D
代替;raw_input
已删除,由input
代替;execfile(filename)
已删除,由exec(open(filename).read())
代替;exec open(filename)
已删除,由exec(open(filename).read())
代替;raise E,V
已删除,由raise E(V)
代替;except E, X:
已删除,由except E as X:
代替;Tkinter
已删除,由tkinter
代替;anydbm
已删除,由dbm
代替;
Python3.0 很大程度地重命名了模块,将他们组织到包中等;
《Learning Python》核心语言,《Programing Python》应用程序设计;
http://www.oreilly.com/catalog/9780596158064/(
MarkLutz. Python学习手册(原书第4版) (Chinese Edition) (Kindle位置200). 机械工业出版社. Kindle 版本.
第一部分 使用入门 —— 第1章 文档环节
Python更注重可读性、一致性和软件值来能;Pyhton支持软件开发的高级重用机制(如OOP);可移植性良好;
Python内置了众多预编译并可移植的功能模块,被称为标准库(standard library);同时Python还有强大的第三方支持工具,如Numpy;
Pyhton脚本的集成也十分灵活;
Python思维:明了胜于晦涩,简洁胜于复杂;(EIBTI import this
)
Python可重用性:模块化、OOP;
Python致力于开发速度的最优化:简介的语法、动态类型、无需编译、内置工具包等,能方便快速完成项目开发;
Python标准实现是将源码编译为字节码,再将字节码解释执行;字节码可移植的;字节码并非底层的二进制代码,因而比C语言要慢;
Numpy是采用双语言混编策略的一个重要例子;
Python在所有的应用领域几乎不所不能;
- 系统开发
- 图形化 Tkinter + PMW,wxPython,PythonCard,Dabo;Python Web框架
- Internet脚本:脚本可以通过套接字进行通信;解析网页等;
- Python web开发工具包: Django,web2py,WebWare;用于构建网站;
- 组件集成
- 数据库编程:对关系型数据库系统的接口;
- Python标准的 pickle模块提供了一个简单的对象持久化系统,处理Python对象到文件类对象的转换;
- ZODB:为Pyhton脚本提供完整的面向对象数据库系统;
- SQLite已经成为Python自带标准库的一部分了;
- 快速原型
- 数值计算和科学计算
- 游戏、AI等领域
- 清华:https://pypi.tuna.tsinghua.edu.cn/simple
- 阿里云:http://mirrors.aliyun.com/pypi/simple/
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
- 华中理工大学:http://pypi.hustunique.com/
- 山东理工大学:http://pypi.sdutlinux.org/
- 豆瓣:http://pypi.douban.com/simple/
- 网易:https://mirrors.163.com/pypi/simple/
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
临时换源:
#清华源
pip install markdown -i https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里源
pip install markdown -i https://mirrors.aliyun.com/pypi/simple/
# 腾讯源
pip install markdown -i http://mirrors.cloud.tencent.com/pypi/simple
# 豆瓣源
pip install markdown -i http://pypi.douban.com/simple/
永久换源:
# 清华源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# 腾讯源
pip config set global.index-url http://mirrors.cloud.tencent.com/pypi/simple
# 豆瓣源
pip config set global.index-url http://pypi.douban.com/simple/
# 换回默认源
pip config unset global.index-url
强大如斯:
- 动态类型
- 自动内存管理
- 大型程序支持
- 内置对象类型
- 内置工具 合并concatenation 分片slice 排序sort 映射mapping
- 库工具 正则匹配到网络支持
- 第三方工具众多
- 简单易用 无需编译 链接动态库的过程
第2章 Python如何运行程序
Python在实现上是一个名为解释器的软件包;解释器是一种让其他程序运行起来的程序;即代码与计算机硬件之间的软件逻辑层;
安装的Python包:包括解释器 和 支持的库;
执行脚本:编译为“字节码” 转发到“虚拟机”
- 字节码执行更快;如果Python进程有写入权限,会把字节码保存为.pyc为扩展名的文件;保存并使用字节码是一种优化;如果源码有变,会重新编译;
- 如果没有写入权限,字节码会在内存中生成,在程序结束时丢弃;
- 字节码是特定于Python的一种表现形式,也是Python程序分发方式之一;
PVM:
- 这并不是一个独立程序,也不惜要安装;就是迭代运行字节码指令的一个大循环;
- PVM是Python的运行引擎(编译得到的代码),是实际运行脚本的组件;
Python产品定制:eval和exec内置模块,能够运行包含Python程序代码的字符串;
Python的动态特性:我们在Python中真正拥有的只有运行时;
Python语言三种实现方式:CPython(C)、Jythpn(Java)、IronPython(Window .NET/Linux Mono);他们都是Python编译器的代替实现;
Psyco:PVM的增强工具,进一步将字节码转换为底层二进制,实现更快的执行速度;目前只能为Intel x86架构的芯片生成机器代码;这个系统大部分似乎最终会被PyPy项目所融合;
冻结二进制文件:将字节码 PVM 以及其他程序所需Python支持文件 捆绑打包为一个单独的可执行文件,更容易想客户分发;py2exe(Windows)、PyInstaller(Linux);
第3章 如何运行程序
交互模式:
- 体验和测试程序;
- 在Python中 *表示数字乘,对于字符串表示重复多次;
- 在Python中 给一个变量赋值之前就使用它,这总是一个错误;
$ python
Python 3.7.2 (default, Dec 29 2018, 00:00:04)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
'Spam' * 8
import os
os.getcwd()
import sys
sys.platform
模块:通常是一个包含了Python语句的简单文本文件;可以直接运行的模块文件也叫脚本:
python script1.py
python script1.py > saveit.txt
支持shell流重定向python script1.py < input.txt
结合input('Input something。。。')
一起使用;
UNIX可执行脚本(#!)
- 第一行特定:以字符
#!
开头,其后紧跟机器Python解释器的路径; - 拥有可执行权限;授权:
chmod + x fle.py
文件 brian:.py
后缀可以省略
#!/usr/local/bin/python
print('hello world!')
模块的导入和重载
每一个Py源码文件都是一个模块;导入模块就是载入另一个文件;
- 被设计为主文件的模块,叫做顶层文件,启动后能运行整个程序的文件;
- 导入文件是另一种运行文件的方法;
- 导入会找文件,编译字节码,运行,是一个开销很大的操作;
- 默认import module只会生效一次,如果需要再次生效,可以使用
- 无论以import 还是 from导入,模块中语句都会执行;
# 避免使用import和reload启动程序
import module1 # 运行一次
import module1 # 不会运行
from imp import reload
reload(module1) # 运行第二次
模块的显要特征:属性
- 模块扮演工具库的角色,往往就是对变量的封装,被认作是命名空间;
- 模块导入时,会生成模块的属性(当前命名空间的变量);使用模块名.属性名 即可获取;
- 也可以直接从模块文件中from导入import变量名(实际上是
复制
,会存在覆盖的可能)
通过import得到具有属性的模块;使用from则会获得文件变量名的副本;
获取模块内可用变量名的列表:dir(modulename)
- 一些以双下划线开头并结尾的变量名,是Python预定义的内置变量名,对于解释器有特定意义;
模块是Python程序最大的程序结构;
- 模块文件在代码文件中起到了最小命名冲突的作用;
要避免使用import和reload启动程序;
使用exec运行模块文件
exec运行文件:
- 就像把文件粘贴到调用exec的地方;
- 由于是粘贴,和from类似,对于当前正在使用的变量有潜在的默认覆盖的可能;
exec(open('test.py').read())
建议不要用exec形式;
错误本身是一种定义良好的机制,叫做异常,可以捕获并处理他们;
Python Docs
IDLE Help菜单 Python Docs选项,或者访问http://www.python.org/doc
;
第二部分 类型和运算 —— 第4章 介绍Python对象类型
Python中数据以对象形式出现:(一切皆对象)
- 程序由模块构成
- 模块包含语句
- 语句包含表达式
- 表达式建立并处理对象
为什么使用内置类型
- 内置对象往往比定制的数据结构更有效率;
核心数据类型:Python语言内部高效创建的;
- 数字:证书1234 浮点数3.1415 复数3+4j 固定精度的十进制数Decimal 带分子分母的有理分数Fraction
- 字符串
- 列表
- 字典
- 元组
- 文件
- 集合:
set('abc') => {'a','b','c'}
- 其他类型:类型 None 布尔型
- 编程单元类型:函数 模块 类
- 与实现相关的类型:变异的代码堆栈跟踪
Python是动态类型(自动跟踪类型,而不要求声明);但也是强类型语言(只能对一个对象进行适合该类型的有效操作);变量在使用前必须赋值;
模块Exp:
math模块包括更高级的书写工具
random模块可作为随机数生成器 和 随机选择器
import random
random.random()
random.choice([1,2,3,4])
字符串时单个字符的字符串序列;
- 字符串 具有 不可变性;
序列的操作
- 使用内置len函数可以验证长度;
- 通过索引得到各个元素;
- 支持反向索引;(从右开始的负数,等价于与序列长度相加 得到的索引值)
- 支持 slice 分片操作;
- 支持加号进行合并,或重复;
'spa' + 'xyz'
/'spa' * 8
;
对于任意的序列对象X和Y:
- X + Y 拼接成新序列
- X * Num 创建Num个X的新序列
字符串特定方法
S.find('pa') # 返回查找到的下标索引
S.replace('pa','XYZ') # 返回新字符串
S.split(',') # 返回根据 指定字符拆分的数组
S.upper()
S.lowervase()
S.isalpha()
S.isdigit()
S.rstrip() # 删除右侧 空白字符(空格 换行 制表符等)
# 字符串格式化
'%s is my name %s' % ('a', 'A')
'{0} is my name {1}'.format('s', 'S')
# 字符转ASCII
ord('\n')
'a'
"b"
"""
多行字符串
"""
r"原始字符串(去掉反斜线转移机制)"
# bytes 类型表示原始字节字符串
如何寻求帮助 查阅对象
调用内置的dir
函数,返回一个列表,包含参数对象的所有属性,包括方法:对于包含下划线的属性,一般表示对象的实现方式,支持定制;如dir(S)
dir函数简单的给出了方法的名称,要查询他们是做什么的,可以将相应的方法名传递给help
函数;如help(S.replace)
模式匹配
字符串对象方法 支持 基于模式的文本处理;
模式匹配需要导入re
模块,其中包含了类似 搜索 分割 替换等调用;
import re
match = re.match('Hello[ \t]*(.*)world', 'Hello Python world')
match.group(1)
# 'Python '
match = re.match('/(.*)/(.*)/(.*)','/usr/home/lua')
match.groups()
# ('usr', 'home', 'lua')
列表
任意类型的对象的位置相关的有序集合,无固定大小;
特定类型操作:
# 对列表修改
L.append('NI')
L.pop(2) # 删除并返回
L.insert(index, value) # insert
L.remove(value) # remove
L.sort() # 改变L自身顺序
L.reverse()# L反转
# 边界检查:Python不允许引用不存在的元素,超出列表索引总会报错;
列表解析:
- 列表解析表达式(同样可以应用于序列)
- 通过对序列中每一项运行一个表达式来创建一个新列表的方法
col2 = [row[1] + 1 for row in M]
[row[1] for row in M if row[1]%2 == 0] # 支持过滤
# 类似的可以使用 map fillter函数
列表解析的其他应用:
- 括号中的解析语法:可以用来创建所需结果的生成器
- 除了创建列表,还可以创建集合、字典;
# 生成器
G = (sum(row) for row in M)
next(G)
next(G)
# map也有类似的效果
list(map(sum, M))
# 集合
{sum(row) for row in M}
# 字典
{i:sum(M[i]) for i in range(3)}
字典
Python中字典不是序列,而是一种映射(mapping),将键映射到值;
Python中的垃圾回收:当最后一次引用对象后(如将这个变量用其他的值进行赋值),这个对象所占用的内存空间将会被自动清理掉;一旦一个对象的最后一次引用被移除,空间将会立即回收;
Python的pickle和shelve模块,用于Python对象持久化;
键排序:
for key in list(D.keys()).sort():
D[key]
# or
for key in sorted(D):
D[key]
列表解析 和 相关的函数编程工具(如map和filter),往往比for循环要更快;
为了测试代码性能,可以使用 time timeit profile模块;
测试不存在的键
获取一个不存在的键是一个错误;
if not 'f' in D:
pass
# or
value = D.get(key, defaultValue)
# or
value = D[key] if key in D else defaultValue
元组
tuple,类似列表,只不过是编写在圆括号中,是一种序列,具有不可变性;支持任意类型和嵌套以及常见的序列操作;
元组专有方法:
T = (1,2,3,4,5,6)
T.index(4) # 获取值4的索引下标 这里是3
T.count(4) # 值4出现的次数
元组提供了一种完整性的约束;对于编写大型程序来说是方便的;
文件
文件对象是Python代码对电脑上外部文件的主要接口;
- 通过内置函数open以字符串形式传入一个外部文件名,以及处理模式字符串;
- read接受一个字节大小的选项
- readline每次读一行
- write写入
- seek移动到一个新的文件位置
- 如今读取一个文件的最佳方式是提供一个迭代器一行一行读;
其他的方法 可以使用 dir help进行查阅;
文件的文本 和 二进制 的读取模式不同:
- 文本文件 内容显示为字符串,并自动执行Unicode编解码
- 二进制文件内容为特定的字节字符串类型;
对于更高级的任务,python还有额外的类文件工具:
- 管道
- 队列
- 套接字:提供网络和进程间通信的接口
- 通过键访问文件
- 对象持久
- 基于描述符的文件:支持文件锁定
- 关系数据库:
- 面向对象数据库接口
集合
不可变的对象的无需集合,通过内置set函数创建,支持一般的数学集合操作;
X & Y
X | Y
X - Y
{x ** 2 for x in [1,2,3,4]}
其他较为重要类型
十进制数(固定精度浮点数)和分数(有一个分子和一个分母的有理数)
- 这两个数值类型,是用来解决浮点数学的局限性和内在的不精确性而添加的;
import decimal
d = decimal.Decimal('3.141')
d + 1
# Decimal('4.141')
decimal.getcontext().prec = 2
decimal.Decimal('1.00') / decimal.Decimal('3.00')
# Decimal('0.33')
from fractions import Fraction
f = Fraction(2,3)
f+1
# Fraction(5,3)
布尔值:
- 预定义的True和False对象 实际是 定制后 以逻辑结果显示的整数1和0;
特殊站位符对象None:
- 通常用来初始化名称和对象;
对象的类型可以通过内置函数type(x)
返回;对象类型的类型是type;
检查对象类型
在代码中检验特定的类型,实际上破坏了Python代码的灵活性;
if type(L) == type([]):
pass
if type(L) == list:
'list 是一个类型名,可以理解为 type类的一个实例'
pass
if isinstance(L, list):
'list 也是 列表对象的 类'
pass
用户定义的类
类定义了新的对象类型,拓展了核心类型;
class Worker:
def __init__(self, name, pay):
self.name = name
self.pay = pay
def lastName(self):
return self.name.splite()[-1]
def giveRaise(self, percent):
self.pay *= (1.0 + percent)
第5章 数字
Python中,数字并非真正的对象类型,而是一组类似类型的分类;
Python数字类型:
- 整数(二进制 八进制 十进制 十六进制) 和 浮点数(对应C语言的双精度浮点型)
- 复数
- 固定精度的十进制数
- 有理分数
- 集合
- 布尔类型
- 无穷的整数精度
- 各种数字内置函数 和 模块
整数
Python3中 整数和长整数合并了,不再需要在末尾添加l或L标识;
二进制(0b/0B
)、八进制(0o/0O
)、十六进制(0x/0X
);
- 内置函数
hex(I)、oct(I)、bin(I)
把一个整数转换为这3中禁止标识的字符串; int(str,base)
根据每个给定的进制把一个运行时字符串转换为整数;int('0x40',16)
;print( '{0:o},{1:x},{2:b}'.format(64,64,64) )
print( '%o, %x, %b' % (64,64,64) )
复数:
3+4j # 复数常量
complex(real, imag) # 一对浮点数进行复数创建
处理数字对象工具:
- 操作符:
+ - * / >> ** &
等 - 内置数学函数:
pow abs round int hex bin
等 - 公用模块:
random math
等 - 特定方法:
as_integer_ratio is_integer bit_length
Python表达式操作符:
yield x # 生成器函数发送协议
lambda args: expression # 生成匿名函数
x if y else z
x or y # 逻辑或 x为假时,才会计算y
x and y
not x
x in y, x not in y # 成员关系
x is y, x is not y # 对象实体测试(对象一致性 严格相等)
x == y, x!=y # 值相等 递归比较所有嵌套对象
x | y # 位或, 集合并集
x ^ y # 位异或, 集合对称差
x & y
x[i:j:k] # 分片
关于除法:
传统除法、Floor除法 和 真除法
Python3 取消了传统除法,
/
表示真除法,//
表示Floor除法;
10/4 = 2.5; 10//4 = 2; 10/4.0 = 2.5; 10//4.0 = 2.0;
如果在2.6版本中要这样使用,可以
from __future__ import division
手动调用内置函数进行强制类型转换:
int(3.14)
float(3)
运算符重载:
- 用类编写的对象代码可以使用+表达式做加法或链接;或使用
[i]
进行索引; - 这种特性叫多态:操作的意义取决于所操作的对象的类型;
数字显示格式:
num = 1/3.0
'%e' % num
'{0:4.3f}'.format(num)
Floor除法VS截断除法:
improt math
math.floor(2.5) # 2
math.floor(-2.5) # -3
math.trunc(2.5) # 2
math.trunc(-2.5) # -2
5/2, 5/-2 # (2.5, -2.5)
5//2, 5//-2 # (2, -3) 这是一个floor除法
5/2.0, 5/-2.0 # (2.5, -2.5)
5//2.0, 5//-2.0 # (2.0, -3.0) 这是一个floor除法
整数精度:Python3整数支持无穷大小;
eval函数:
- 把传入的字符串参数作为Python代码片段,编译并运行这个字符串;
位操作:
x = 1
x << 2 # 4
x | 2 # 3 按位或
x & 1 # 1 按位与
bit_length方法:查询以二进制表示一个数字的值所需的位数
X = 99
bin(X), X.bit_length() # ('0b1100011', 7)
(256).bit_length() # 9
len(bin(256)) - 2 # 9
其他的内置数学工具:
import math
math.pi , math.e
math.sin(2*math.pi/180)
math.sqrt(2)
pow(2,4), 2**4
abs(-42)
sum((1,2,3,4))
min(1,3,5,7)
max(2,4,6,8)
rount(2.567) # 3 四舍五入
import random
random.random() # 0-1之间小数
random.randint(1,10) # 1-10之间整数
random.choice(['a','b','c'])
像abs这样内置函数位于一个隐形的命名空间内,在Python3中对应在名为
builtins
的模块;
固定精度的十进制数
要注意:浮点数学缺乏精确性,因为采用存储数值的空间有限;
- 使用小数对象,结果会得到改正;
- 通过
decimal.Decimal.from_float(1.25)
将浮点对象创建为小数对象,这一转换是精确的; - decimal模块上下文对象允许指定精度和舍入模式(舍去、进位),该精度全局性地适用于调用线程中创建的小数;
0.1+0.1+0.1-0.3 # 并不是0
from decimal import Decimal
Decimal('0.1') + Decimal('0.1') + Decimal('0.1')- Decimal('0.3') # Decimal('0.0')
decimal.getcontext().prec = 4 # 全局
with decimal.localcontext() as ctx:
ctx.prec = 2 # 局部
有理分数
分数类型:
- 实现有理数对象,明确保留一个分子和分母,从而避免浮点数学的某些不精确性和局限性;
- 为了支持分数转换,浮点数对象的
as_integer_ratio()
方法能够得到一个分子,分母的元组; - 分数有一个
from_float
方法; - float函数接收一个Fraction作为参数;
from fractions import Fraction
f = 2.5
z = Fraction(*f.as_as_integer_ratio()) # 这里用到了元组解包
Fraction.from_float(1.75)
float(Fraction(1,3))
某些情况下,将浮点数转换为分数,会损失精度,因为最初的浮点形式就是不精确的;
集合
集合:
- 集合set,是一些唯一的、不可变的对象的一个无序集合collection;
- 这些对象支持与数学集合理论相对应的操作;
要创建一个集合对象,向内置的set函数传入一个序列或可迭代的对象:
x = set('abcde') # 空集合必须通过set函数创建
y = {'b','d','x','y','z'} # 集合常量
'e' in x
x - y
x & y
x | y
x ^ y
x > y, x < y # 返回布尔值 前者表示x是y的超集 后者表示x是y的子集
# 改变集合的方法
z = x.intersection(y) # 交集
x.union(y)
x.issubset(range(-5,5))
z.add('span') # 插入
z.update(set(['X','Y'])) # 合并
z.remove('b') # 删除
集合是一个可迭代的对象;但由于无序,因此不支持索引和分片;
同时要注意,集合只能包含不可变(即可散列的)对象类型;
如果需要在一个集合中嵌入另一个集合,可以使用frozenset
,用法和set一样;他创建的是一个不可变的集合;
集合的解析构造:{x ** 2 for x in [1,2,3,4] }
集合的应用:
L = [1,2,3,412,3]
set(L)
L = list(set(L)) # 去重
布尔类型
布尔型(bool
),置为True 和 False,是内置整数类型int的子类;
- 行为上和1 0 一直;但有特定的显示逻辑;
- bool为True False两个对象重新定义了str和repr的字符串格式;
数字扩展
NumPy(Numeric Pyhton)提供了高级的数学编程工具,如矩阵 向量 和 高级计算的库;
第6章 动态类型简介
动态类型是Python语言灵活性的根源;
- 变量在赋值时才创建;它可以引用任何类型的对象;
- 变量是一个系统表的元素,用于指向对象的连接的空间;
- 对象是分配的一块内存,有足够的空间去表示他们所代表的值;
- 引用是自动形成的从变量到对象的指针;
对象的垃圾收集
引用计数器:记录当前指向对象的引用的数目;一旦这个计数器被设置为0,这个对象的内存空间就会被自动回收;(大多数种类的对象都会在不再引用时马上回收,某些不会被回收的,会被保留在一个系统表中,下次生成同值对象时可被复用,这是一种缓存机制,与代码并没有什么关系)
此外,也有一部分Python功能可以及时检测并回收带有循环引用的代码(该功能可开关);更多引用循环的场景一定要区别对待,因为它们的引用计数不会清零;
给一个变量赋一个新值,并不是替换了原始的对象,而是让这个变量去引用完全不同的一个对象;
获取对象的引用计数:
import sys
sys.getrefcount(obj_a) # 这个值 是包含缓存的 所以并没有什么应用意义
列表对象拷贝
内置的列表函数,标准库copy模块,从头到尾的切片;
import copy
copy.copy(L)
copy.deepcopy(L)
相等判断
L == M
值相等L is M
对象同一性
第7章 字符串
一个有序的字符集合;存储字节的绝对二进制值,多字节的Unicode;
Python没有单独字符这种类型,而是使用一个字符的字符串;
len(s)
"%s %s" % para1
"%s %s" % (para1,para2) # 普通的字符串格式化
"%(n)d %(x)s" % {'n':1, 'x':'spam'} # 基于字典的字符串格式化
"{0}".format(para) # 新的字符串格式化
template = '{motto},{0} and {food}' # 更python的用法
template.format('ham', motto="spam", food="eggs")
s.find('pa')
s.rstrip() # 移除空格
s.replace('pa','xx')
s.split(',')
s.isdigit()
s.lower()
S.endwith('spam')
'spam'.join(',')
S.encode('latin-1')
'spam' in S
map(ord, s)
标准库re模块(正则)提供了基于模式的字符串处理;
Python还带有很多字符串工具;
Python3中的3中字符串类型:
- str 用于 Unicode(ASCII或其他)
- bytes 二进制数据(包括编码的文本)
- bytearray 是bytes的一种可变的变体
字符串常量:
- 单引号、双引号、三引号
- 包含转移字符
- Raw字符串:
r"C:\new"
抑制转义 - Byte字符串:
b"\x01"
raw字符串不能以单个的反斜杠结尾;因为会转义后续的引用字符;
Python切片是一个左闭右开区间;
分片对象:
'spam'[1:3]
'spam'[slice(1,3)]
'spam'[::-1]
'spam'[slice(None,None,-1)]
系统命令行中启动Python程序时,罗列参数,可以使用内置的sys模块中的argv属性;
字符串代码转换:
ord('s')
转ASCII码;chr(115)
转字符;
bytearray对象不是真正的字符串,是较小的8位整数序列;支持和常规字符串相同的大多数操作,显示为ASCII字符;
字符串的方法调用,可使用dir进行查看;以下是一些常用的:
s.replace('old','new')
s.find('substr')
list(S)
s.split()
s.split(',')
''.join(L)
'SPAM'.join(['AA','BB'])
#
s.rstrip()
s.upper()
s.isalpha()
s.endswith('str')
s.startwith('str')
新的字符串格式化:
template = '{motto},{0} and {food}' # 更python的用法
template.format('ham', motto="spam", food="eggs")
import sys
'My {1[spam]} runs {0.platform}'.format(sys, {'spam':'laptop'})
'first={0[0]}, third={0[2]}'.format([1,2,3,4])
数字的千分隔位语法:
'{0:,d}'.format(9999999999)
'{0:,.2f}'.format(9999999999.999)
字符串前加 f
import time
t0 = time.time()
time.sleep(1)
name = 'processing'
# 以 f开头表示在字符串内支持大括号内的python 表达式
print(f'{name} done in {time.time() - t0:.2f} s')
第8章 列表与字典
列表
列表(list)有序集合对象类型,可以包含任何种类的对象;
L = []
L = list(range(-4,4))
len(L)
3 in L
L.append(4)
L.extend([5,6,7])
L.insert(I, X)
L.index(1)
L.count(X)
L.sort() # 修改的是原列表
L.reverse()
del L[I]
del L[i:j]
L.pop()
L.pop(0)
L.remove(X)
L[i:j] = []
[x**2 for x in range(5)]
list(map(ord, 'spam'))
L = ['bac', 'ABD', 'aBe']
L.sort(key=str.lower, reverse=True) # 仅支持同类型排序
sorted(L, key=str.lower, reverse=True) # 会返回排序后的新list
字典
字典(dictionary,类型名为dict),作为内置类型,字典可以取代许多搜索算法和数据结构;
本质上,字典作为散列表(支持快速检索的数据结构)实现的,一开始很小,根据要求而增大;Python采用最优化的散列算法来寻找键,搜索很快;
D = dict.fromkeys(['a', 'b'], defalutVal) # 不设默认值 则为None
D = dict(zip(keyslist, valslist))
D = dict(name='aaa', age=42)
'key' in D
D.keys() # 返回的是可迭代的视图 而非列表
D.values() # 返回的是视图
D.items() # 返回的是视图
list(D.items()) # 返回的是一个元组的列表
D.copy()
D.get(key, default) # 不存在时不会报错,不设默认值 则为None
D.update(D1) # 合并
D.pop(key)
len(D)
del D[key]
{x:x**2 for x in range(10)}
字典的键可以是任何不可变对象;
Python的DBM接口通过键来获取文件:
import anydbm
file = anydbm.open("filename")
file['key'] = 'data'
data = file['key']
shelve同样使用字典接口,shelve通过键来访问Python持久对象的数据库;Python的CGI脚本支持的一个接口看上去也和字典类似;
字典视图:有点类似集合的一种数据对象
D.keys() & D.keys() # { key1, key2, ... }
D = {'a': 1}
D.items() | D.keys() # {('a', 1), 'a'}
第9章 元组、文件及其他
元组
元组(tuple):最后一个Python集合类型;
- 具有不可变性;元组的不可变性提供了某种完整性;
- 是一个位置有序的对象的集合;
- 通过偏移访问
- 固定长度、异构、任意嵌套;
T = ()
T = (0,)
T = tuple('spam')
T[i]
T1 + T2 # 合并
T.index(val)
T.count(val)
单词元组借用自数学领域,通常用来指关系数据库表的一样;
文件
内置open函数会创建一个Python文件对象,可以作为计算机上的一个文件链接;返回的文件对象相关方法来读写外部文件;
output = open(r'path', 'w')
input = open(r'path', 'r')
input.read()
input.read(N)
input.readline()
input.readlines()
output.write(str)
output.writelines(strList)
output.close()
output.flush() # 把缓冲区刷到磁盘,但不关闭文件
anyFile.seek(N) # 修改文件位置到偏移量N
for line in open('path'):
line = line.rstrip()
use line # 文件迭代器 按行读取
open('f.txt', encoding='latin-1')
open('f.bin', 'rb')
打开文件的处理模式:
r
读取w
写入a
追加- 尾部加上
b
对二进制数据处理 +
同时为输入和输出打开文件
文件迭代器是最好的读取行工具;
关闭会释放操作系统资源,也清空了缓冲区;默认写入的文本不会立即从内存转换到磁盘,直到关闭或运行flush方法;
Python文件是在字节偏移基础上随机访问的,seek方法允许脚本跳转到指定位置进行读写;
对于一个列表或字典的字符串,如果要将其转换为正常的列表和字典对象,可以运行内置函数eval:eval能把字符串当做可执行程序代码;
可惜的是eval的功能往往过于强大,甚至会执行删除文件的表达式;如果想存储Python原生对象,但又无法信任数据来源,标准库的pickle
模块会是个理想选择;
pickle:
- 该模块能够让我们直接在文件中存储几乎任何Python对象的高级工具;
- pickle模块执行所谓的对象序列化;(对象 <=> 字节字符串)
D = {'a':1, 'b':2}
F = open('datafile.pkl', 'wb')
import pickle
pickle.dump(D, F)
F.close()
F = open('datafile.pkl', 'rb')
E = pickle.load(F)
# {'a':1, 'b':2}
shelve:
- shelve用pickle把python对象存放到按键访问的文件系统中;
struct模块能够构造并解析打包的二进制数据;
文件的向下文管理器:
- 比文件自身多了一个异常处理功能;
- 确保退出后自动关闭文件,而不是依赖于垃圾收集上的自动关闭;
with open(r'path') as myfile:
for line in myfile:
pass
其他文件工具
文件方法清单:help dir(一个打开的文件对象,或名称file)
- 标准流:在sys模块中预先打开的文件对象,如sys.stdout
- os模块中的描述文件:处理整数文件,支持诸如文件锁定之类的较低级工具;
- sockets、pipes和FIFO文件:文件类对象,用于同步进程或者通过网络进行通信;
- 通过键来存取的文件:通过键直接存储的不变的Python对象
- Shell命令流:像os.popen和subprocess.Popen,支持产生shell命令,并读取和写入到标准流;
要点:
- 对象更具分类来共享操作;
- 数字包含了所有数字类型;
- 集合类似一个无值的字典的键;集合不是一个映射类型或者一个序列类型,无序;
对象分类:
- 数字 数值分类
- 字符串 序列分类
- 列表 序列分类 可变
- 字典 对应分类 可变
- 元组 序列分类
- 文件 扩展分类
- Sets 集合分类 可变
- frozenset 集合
- bytearray 序列 可变
自定义序列对象:重载 索引和合并等操作
class MySequence:
def __setitem__(self, value):
pass
def __getitem__(self, index):
# self[index]
pass
def __add__(self, other):
# self + other
pass
对象拷贝
- 顶层拷贝:没有限制条件的分片表达式能够复制序列,无条件指的是
L[:]
; - 顶层拷贝:字典copy方法能够复制字典
- 顶层拷贝:有些内置函数能够生成拷贝(如
list(L)
) - 顶层拷贝 和 深层拷贝:copy标准库模块能够生成完整拷贝;
import copy
X = copy.deepcopy(Y)
字典的比较
不能直接比较,可以使用如下方式:
D1 = {'a':1, 'b':2}
D2 = {'a':1, 'b':3}
sorted(D1.items()) < sorted(D2.items()) # True
真假的含义
- 数字:零假,非零真;
0.0 => False
- 其他对象:空假,非空真;
None => False; [] => False; {} => False; '' => False
Python提供了一个内置函数bool()
,可以用来测试一个对象的布尔值;
None是Python中一种特殊数据类型的唯一值,一般做空的占位符;
- 是一块内存,是一个真正的对象;
- 还是函数的默认返回值;
Python的类型层次(重要)
root | layer1 | layer2 | layer3 |
---|---|---|---|
Collections | Sequences | Immutable | String |
— | — | — | Unicode(2.6) |
— | — | — | Bytes(3.0) |
— | — | — | Tuple |
— | — | Mutable | List |
— | — | — | Bytearray(3.0) |
— | Mappings | Dictionary | — |
— | Sets | set | — |
— | — | Frozenset | — |
Numbers | Integers | Integer | — |
— | — | Long(2,6) | — |
— | — | Boolean | — |
— | Float | — | — |
— | Complex | — | — |
— | Decimal | — | — |
— | Fraction | — | — |
Callables | Function | — | — |
— | Generator | — | — |
— | Class | — | — |
Method | Bount | — | — |
— | Unbound(2.6) | — | — |
Other | Module | — | — |
— | Instance | — | — |
— | File | — | — |
— | None | — | — |
— | View(3.0) | — | — |
Internals | Type | — | — |
— | Code | — | — |
— | Frame | — | — |
— | Traceback | — | — |
Python中所有一切都是某种类型的对象,即便是某个对象的类型;任何对象的类型都是类型为type的对象;
类型内置名:dict list str typle int float complex byte type set file
- 调用这些名称 实际是对这些对象构造函数的调用;
- 作为基本的,还可以把它们当做简单的转换函数;
type([1]) == type([])
type([1]) == list
isinstance([1], list)
import types
def f():
pass
type(f) == types.FunctionType
Python其他类型:函数 模块 类 正则表达式对象 DBM文件 GUI组件 网络套接字等;