2021-07-28 读书笔记:Python 学习手册(1)

读书笔记: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等领域

PyPI网站国内镜像源列表(from)

  • 清华: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组件 网络套接字等;


你可能感兴趣的:(Python)