包管理程序 pip
使用 pip 安装 Python 模块
1 | python3 -m pip install SomePackage |
pip 其它选项
| 选项 | 说明 |
|---|---|
--trusted-host <host> |
信任的主机名 |
--retries <N> |
重试次数 |
--timeout <sec> |
设置超时时间 |
--proxy <proxy> |
指定代理 |
--no-cache-dir |
禁用缓存 |
pip install 其它选项
| 选项 | 说明 |
|---|---|
-i,--index-url <url> |
指定 url, 默认为 https://pypi.python.org/simple/ |
--no-deps |
不安装依赖 |
-t,--target <dir> |
安装至 dir |
-d,--download <dir> |
仅下载至 dir,不安装 |
-r,--requirement <file> |
安装在 file 中列出需要安装的包,file 包含由 pip install 参数排成列表的文件 |
pip 配置文件
unix: $HOME/.pip/pip.conf
win: %HOME%\pip\pip.ini
1 | [global] |
pip 自动补全
1 | pip3 completion --bash >> ~/.profile |
安装使用 Python
Linux下从源代码构建
- 下载最新Python 源代码 https://www.python.org/downloads/source/
- 构建
1 | ./configure |
make install 会覆盖系统中已安装的Python 版本
查看configure 配置 ./configure --help
| configure 选项 | 说明 |
|---|---|
| –prefix=PREFIX | 指定PREFIX 安装架构无关的文件,默认为 /usr/local |
| –exec-prefix=EPREFIX | 指定PREFIX 安装依赖架构的文件 |
文件安装路径
| 文件/目录 | 说明 |
|---|---|
exec_prefix/bin/python3 |
解释器的推荐位置 |
prefix/lib/pythonversion, exec_prefix/lib/pythonversion |
包含标准模块的目录的推荐位置 |
prefix/include/pythonversion, exec_prefix/include/pythonversion |
包含开发Python扩展和嵌入解释器所需的include文件的目录的推荐位置 |
查看 Python3 版本号 python3 --version
Python 解释器
终端执行 python3 进入交互式 Python, 键入 Ctrl-D 退出交互式(windows 下是Ctrl-Z), 或者输入 sys.exit() 退出(需要先 import sys)
python3 提供和bash 类似的 -c 选项以执行一条语句 python3 -c command [arg] ...
python3 file 用以解释执行 Python 源文件, Linux 下Python默认的字符编码是 UTF-8, 可以在源文件第一行指定编码
1 | # -*- coding: utf-8 -*- |
如果第一行以 shebang 开头,则在第二行指定编码
1 | #!/usr/bin/env python3 |
作用域和名称空间
global, nonlocal
1 | global_stmt ::= "global" identifier ("," identifier)* |
global
1 | var = 'global var' |
global 语句是作用于整个当前代码块的声明,用于给全局变量赋值
在 global 语句中列出的名称不得在同一代码块内该 global 语句之前的位置中使用;例如下面的代码语法是错误的
1 | a = 1 |
nonlocal
1 | def func1(): |
nonlocal 语句会使得所列出的名称指向之前在最近的包含作用域中绑定的除全局变量以外的变量
与 global 语句中列出的名称不同,nonlocal 语句中列出的名称必须指向之前存在于包含作用域之中的绑定(在这个应当用来创建新绑定的作用域不能被无歧义地确定)
nonlocal 语句中列出的名称不得与之前存在于局部作用域中的绑定相冲突
以下代码的语法是错误的
1 | var = 'global var' |
模块和包
模块
Python 模块即一个 Python 源文件(.py)
全局变量 __name__ 定义了模块名,以 python3 xxx.py <arguments> 运行模块时,__name__ 赋值为 "__main__",因此可以添加如下代码让该模块仅当脚本运行时才执行这些语句
1 | if __name__ == "__main__": |
import
1 | import_stmt ::= "import" module ["as" identifier] ("," module ["as" identifier])* |
import, import-from 语句用来导入其它模块,import 模块时会执行模块中的语句,导入模块中的符号
import 语句
- 查找一个模块,如果有必要还会加载并初始化模块
- 在局部命名空间中为 import 语句发生位置所处的作用域定义一个或多个名称
import-from 语句
- 查找 from 子句中指定的模块,如有必要还会加载并初始化模块
- 对于 import 子句中指定的每个标识符
- 检查被导入模块是否有该名称的属性
- 如果没有,尝试导入具有该名称的子模块,然后再次检查被导入模块是否有该属性
- 如果未找到该属性,则引发
ImportError - 否则的话,将对该值的引用存入局部命名空间,如果有 as 子句则使用其指定的名称,否则使用该属性的名称
假如文件 moudle.py 定义了函数 func,那么,可以在其它文件中 import moudle 后,通过 moudle.func() 调用该模块中的函数,模块名后使用 as 时,直接把 as 后的名称与导入模块绑定
from moudle import * 可以导入模块内定义的所有名称
模块的搜索路径
搜索模块 spam 的顺序
- 查找名为
spam的内置模块 - 从
sys.path中查找文件spam.py
sys.path 初始时包含
- 输入脚本的目录(或未指定文件时的当前目录)
PYTHONPATH(目录列表,与 shell 变量 PATH 的语法一样)- 默认安装目录
1 | import sys |
包
包是一种组织模块的结构,可以用来构造Python 的名称空间
一个包含Python 模块的目录要称为包,需要在目录下编写一个 __init__.py 的文件,最简单的情况下,该文件为空;也可以执行包的初始化代码,或设置 __all__ 变量
对于 from package import item
item 可以是包的子模块(或子包),也可以是包中定义的函数、类或变量等其他名称。import 语句首先测试包中是否定义了 item;如果未在包中定义,则假定 item 是模块,并尝试加载。如果找不到 item,则触发 ImportError 异常
对于 from package import *
- 如果包的
__init__.py代码定义了列表__all__,就导入列表中的模块 - 如果没有定义
__all__- 不会把包中所有子模块都导入到当前命名空间
- 只确保导入包 package(可能还会运行
__init__.py中的初始化代码) - 然后,再导入包中定义的名称。这些名称包括
__init__.py中定义的任何名称(以及显式加载的子模块),还包括之前 import 语句显式加载的包里的子模块
在包中引入其它模块或子包中的模块,可用相对形式导入(基于当前模块名)
1 | from . import echo |
由于,主模块名是 "__main__" ,因此,Python 应用程序的主模块必须始终使用绝对导入
函数
定义函数
1 | funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" |
1 | def fib(n): |
- 函数定义使用
def,后跟函数名和参数列表 - 函数内的第一条语句是字符串时,称为文档字符串(docstring)
- 没有
return或return不带表达式的函数返回None
默认参数
1 | def func(a, b = 0): |
调用时需给出必选参数,可选参数按顺序给定
1 | i = 5 |
默认值在定义作用域里的函数定义中求值
1 | def f(a, L=[]): |
默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果
不想在后续调用之间共享默认值时,应以如下方式编写函数
1 | def f(a, L=None): |
关键字参数
1 | def func(a, b = 1, c = 2): |
- 调用函数时可用
kwarg=value形式的关键字参数 - 函数调用时,关键字参数必须跟在位置参数后面
- 关键字参数的顺序并不重要。这也包括必选参数
- 不能对同一个参数多次赋值
- 所有传递的关键字参数都必须匹配一个函数接受的参数
最后一个形参为 **name 形式时,接受一个字典,**name 形参可以与 *name 形参(下一小节介绍)组合使用(*name 必须在 **name 前面)*name 形参接收一个元组,该元组包含形参列表之外的位置参数
1 | def func(a, *b, **c): |
lambda
1 | lambda_expr ::= "lambda" [parameter_list] ":" expression |
lambda 创建匿名函数 如 (lambda x: x ** 2)(5) 创建一个匿名函数并调用
lambda parameters: expression 类似于如下方式定义函数
1 | def <lambda>(parameters): |
数据类型
内置类型
Nonenumbers.Numbernumbers.Integralintbool
numbers.Real(float)numbers.Complex(complex)
- 序列
- 不可变序列
- 字符串(
str) - 元组(
tuple) - 字节串(
bytes) - 范围(
range)
- 字符串(
- 可变序列
- 列表(
list) - 字节数组(
bytearray)
- 列表(
- 不可变序列
- 集合
- 集合(
set) - 冻结集合(
frozenset)
- 集合(
- 映射
- 字典(
dict)
- 字典(
数字类型
int
整数类型,拥有无限精度
构造函数 int() 用以构造 int 类型数字
int 类型的按位运算
| 运算 | 结果 |
|---|---|
| `x | y` |
x ^ y |
按位异或 |
x & y |
按位与 |
x << n |
左移 (n >= 0) |
x >> n |
右移 (n >= 0) |
~x |
按位取反 |
int 类型的方法,字面量调用如 1.bit_length() 是错误的语法,可改成 (1).bit_length()
bool 类型
bool 类型是两个常量对象之一: True, False,可用内置函数 bool() 将任意值转为 bool 类型
float 类型
一般使用C 语言的 double 来实现,浮点数构造函数 float()
complex 类型
复数包含实部和虚部,分别以一个浮点数表示。 要从一个复数 z 中提取这两个部分,可使用 z.real 和 z.imag
复数构造函数 complex()
数字类型的运算
| 运算 | 结果 |
|---|---|
x + y |
和 |
x - y |
差 |
x * y |
乘积 |
x / y |
商 |
x // y |
整除 |
x % y |
模 |
-x |
取反 |
+x |
x 不变 |
abs(x) |
绝对值 |
int(x) |
转为整数 |
float(x) |
转为浮点数 |
pow(x, y) |
x 的 y 次幂 |
x ** y |
x 的 y 次幂 |
divmod(x, y) |
(x // y, x % y) |
complex(re, im) |
带有实部re, 虚部im(默认0) 的复数 |
c.conjugate() |
复数c 的共轭 |
序列类型
通用序列(可变与不可变序列)操作
| 运算 | 结果 |
|---|---|
x in s |
如果 s 中的某项等于 x 则结果为 True,否则为 False |
x not in s |
如果 s 中的某项等于 x 则结果为 False,否则为 True |
s + t |
s 与 t 相拼接 |
s * n 或 n * s |
相当于 s 与自身进行 n 次拼接 |
s[i] |
第 i 项(从0起) |
s[i:j] |
s 从 i 到 j 的切片 |
s[i:j:k] |
s 从 i 到 j 步长为 k 的切片 |
len(s) |
s 的长度 |
min(s) |
s 的最小项 |
max(s) |
s 的最大项 |
s.index(x[, i[, j]]) |
x 在 s 中首次出现项的索引号(索引号在 i 或其后且在 j 之前) |
s.count(x) |
x 在 s 中出现的总次数 |
相同类型的序列支持比较操作
不可变序列类型普遍实现而可变序列类型未实现的唯一操作就是对 hash() 内置函数的支持
可变序列操作
| 运算 | 结果 |
|---|---|
s[i] = x |
将 s 的第 i 项替换为 x |
s[i:j] = t |
将 s 从 i 到 j 的切片替换为可迭代对象 t 的内容 |
del s[i:j] |
等同于 s[i:j] = [] |
s[i:j:k] = t |
将 s[i:j:k] 的元素替换为 t 的元素 |
del s[i:j:k] |
从列表中移除 s[i:j:k] 的元素 |
s.append(x) |
将 x 添加到序列的末尾 (等同于 s[len(s):len(s)] = [x]) |
s.clear() |
从 s 中移除所有项 (等同于 del s[:]) |
s.copy() |
创建 s 的浅拷贝 (等同于 s[:]) |
s.extend(t) 或 s += t |
用 t 的内容扩展 s (基本上等同于 s[len(s):len(s)] = t) |
s *= n |
使用 s 的内容重复 n 次来对其进行更新 |
s.insert(i, x) |
在由 i 给出的索引位置将 x 插入 s (等同于 s[i:i] = [x]) |
s.pop([i]) |
提取在 i 位置上的项,并将其从 s 中移除,可选参数 i 默认为 -1,移除并返回最后一项 |
s.remove(x) |
删除 s 中第一个 s[i] 等于 x 的项目 |
s.reverse() |
就地将列表中的元素逆序 |
字符串
Python 中的字符串是 str 类型,是由 Unicode 码位构成的不可变序列
字符串字面量的三种写法
- 单引号:
'允许包含有 "双" 引号' - 双引号:
"允许包含有 '单' 引号" - 三重引号:
'''三重单引号''', """三重双引号"""
使用三重引号的字符串可以跨越多行 —— 其中所有的空白字符都将包含在该字符串字面值中,由空格分隔的字符串字面量会转换成单个字符串
字符串构造函数 str()
对于字符串 s, s[i] 将产生长度为1 的字符串(Python 中没有字符类型),s[i] == s[i:i+1]
格式化字符串
- 格式字符串字面值(
f-string): 以f/F为前缀,{}为标记 - printf 风格格式化字符串
format % values str.format()
1 | nums = 100 |
元组
元组是不可变序列,通常用于储存异构数据的多项集,也被用于需要同构数据的不可变序列的情况
构建元组的方式
- 使用一对圆括号来表示空元组:
() - 使用一个后缀的逗号来表示单元组:
a,或(a,) - 使用以逗号分隔的多个项:
a, b, c或(a, b, c) - 使用内置的
tuple():tuple()或tuple(iterable)
决定生成元组的其实是逗号而不是圆括号,圆括号只是可选的,生成空元组或需要避免语法歧义的情况除外
元祖拆包(可迭代元素拆包)
1 | point = (1, 2) |
字节串
bytes 对象是由单个字节构成的不可变序列
bytes 字面量(类似str 字面量,有一个前缀b)
- 单引号:
b'同样允许嵌入 "双" 引号' - 双引号:
b"同样允许嵌入 '单' 引号" - 三重引号:
b'''三重单引号''', b"""三重双引号"""
str, bytes 字面量通过前缀 r 禁用转义序列
bytes 构造函数 bytes()
范围
range 类型表示不可变的数字序列,通常用于在 for 循环中循环指定的次数
构造函数
range(stop)range(start, stop[, step])
1 | list(range(10)) |
列表
列表是可变序列,通常用于存放同类项目的集合
构造列表的方式
- 使用一对方括号来表示空列表:
[] - 使用方括号,其中的项以逗号分隔:
[a],[a, b, c] - 使用列表推导式:
[x for x in iterable] - 使用类型的构造器:
list()或list(iterable)
列表推导式
1 | symbols = '$¢£¥€¤' |
生成器表达式
1 | symbols = '$¢£¥€¤' |
- 如果生成器表达式是一个函数调用过程中的唯一参数,那么不需要额外再用括号把它围起来
- 生成器表达式会在每次for循环运行时才生成一个组合
字节数组
bytearray 对象是 bytes 对象的可变对应物
bytearray 总是通过调用构造器来创建 bytearray()
集合
集合是由具有唯一性的 hashable 对象所组成的无序多项集
set 类型是可变的,其内容可以使用 add() 和 remove() 这样的方法来改变。由于是可变类型,它没有哈希值,且不能被用作字典的键或其他集合的元素
frozenset 类型是不可变并且为 hashable,其内容在被创建后不能再改变;因此它可以被用作字典的键或其他集合的元素
构造函数分别为 set() frozenset()
非空的 set (不是 frozenset) 还可以通过将以逗号分隔的元素列表包含于花括号之内来创建,例如: {'jack', 'sjoerd'}
字典
映射对象会将 hashable 值映射到任意对象,Python 提供 dict 映射类型,dict 属于可变对象
创建字典
- 字面量: 包含与
{}内的key:value列表,如{'jack': 4098, 'sjoerd': 4127} - 字典推导式:
{},{x: x ** 2 for x in range(10)} - 构造函数
dict:dict(),dict([('foo', 100), ('bar', 200)]),dict(foo=100, bar=200)
字典的操作
| 操作 | 说明 |
|---|---|
list(d) |
返回字典 d 中使用的所有键的列表 |
len(d) |
返回字典 d 中的项数 |
d[key] |
返回 d 中以 key 为键的项。 如果映射中不存在 key 则会引发 KeyError |
d[key]=value |
将 d[key] 设为 value |
del d[key] |
将 d[key] 从 d 中移除。 如果映射中不存在 key 则会引发 KeyError |
key in d |
如果 d 中存在键 key 则返回 True,否则返回 False |
key not in d |
等价于 not key in d |
iter(d) |
返回以字典的键为元素的迭代器。 这是 iter(d.keys()) 的快捷方式 |
clear() |
移除字典中的所有元素 |
copy() |
返回原字典的浅拷贝 |
fromkeys(iterable[, value]) |
使用来自 iterable 的键创建一个新字典,并将键值设为 value |
get(key[, default]) |
如果 key 存在于字典中则返回 key 的值,否则返回 default。 如果 default 未给出则默认为 None,因而此方法绝不会引发 KeyError |
items() |
返回由字典项(key-value)组成的一个新视图 |
keys() |
返回由字典键(key)组成的一个新视图 |
values() |
返回由字典值组成的一个新视图 |
pop(key[, default]) |
如果 key 存在于字典中则将其移除并返回其值,否则返回 default。 如果 default 未给出且 key 不存在于字典中,则会引发 KeyError |
popitem() |
从字典中移除并返回一个 (键, 值) 对。 键值对会按 LIFO 的顺序被返回 |
reversed(d) |
返回一个逆序获取字典键的迭代器。 这是 reversed(d.keys()) 的快捷方式 |
setdefault(key[, default]) |
如果字典存在键 key ,返回它的值。如果不存在,插入值为 default 的键 key ,并返回 default 。 default 默认为 None |
update([other]) |
使用来自 other 的键/值对更新字典,覆盖原有的键 |
| `d | other` |
| `d | = other` |
其它内置函数
enumerate(iterable, start=0) 返回一个枚举对象
1 | lists = ["hello", "world"] |
zip(*iterables) 创建一个聚合了来自每个可迭代对象中的元素的迭代器,返回一个元组的迭代器
- 其中的第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素
- 当所输入可迭代对象中最短的一个被耗尽时,迭代器将停止迭代
- 当只有一个可迭代对象参数时,它将返回一个单元组的迭代器
- 不带参数时,它将返回一个空迭代器
1 | list1 = [1, 2] |
流程控制语句
逻辑值检测
一个对象在默认情况下均被视为真值,除非当该对象被调用时其所属类定义了 __bool__() 方法且返回 False 或是定义了 __len__() 方法且返回零
以下对象为假值
- 常量
None,False - 数值类型的零:
0, 0.0, 0j, Decimal(0), Fraction(0, 1) - 空的序列和多项集:
'', (), [], {}, set(), range(0)
布尔运算
- x
ory: 如果x 为假, 则y, 否则x(x 为真时短路) - x
andy: 如果x 为假, 则x, 否则y(x 为假时短路) notx: 如果x 为假, 则True, 否则False
比较运算符
| 运算 | 含义 |
|---|---|
< |
严格小于 |
<= |
小于或等于 |
> |
严格大于 |
>= |
大于或等于 |
== |
等于 |
!= |
不等于 |
is |
对象标识 |
is not |
否定的对象标识 |
in |
成员运算检测 |
not in |
否定的成员运算检测 |
比较运算符优先级相同,且高于布尔运算
比较运算可以任意串连;例如,x < y <= z 等价于 x < y and y <= z,前者的不同之处在于 y 只被求值一次(但在两种情况下当 x < y 结果为假值时 z 都不会被求值)
if
1 | if_stmt ::= "if" assignment_expression ":" suite |
1 | string = 'hello' |
while
1 | while_stmt ::= "while" assignment_expression ":" suite |
1 | i = 0 |
for
1 | for_stmt ::= "for" target_list "in" expression_list ":" suite |
1 | lists = ['hello', 'world'] |
break, continue
while, for 语句中的 break, continue 分别用以终止循环与跳过循环内剩余语句
try
1 | try_stmt ::= try1_stmt | try2_stmt |
1 | try: |
with
1 | with_stmt ::= "with" with_item ("," with_item)* ":" suite |
1 | with open("test.txt", "r") as f: |
pass
pass 用以占位
1 | def f(arg): pass |
容器
array.array
1 | from array import array |
| 类型码 | C类型 | Python 类型 | 最小字节大小 |
|---|---|---|---|
'b' |
signed char |
int |
1 |
'B' |
unsigned char |
int |
1 |
'u' |
wchar_t |
Unicode 字符 | 2 |
'h' |
signed short |
int |
2 |
'H' |
unsigned short |
int |
2 |
'i' |
signed int |
int |
2 |
'I' |
unsigned int |
int |
2 |
'l' |
signed long |
int |
4 |
'L' |
unsigned long |
int |
4 |
'q' |
signed long long |
int |
8 |
'Q' |
unsigned long long |
int |
8 |
'f' |
float |
float |
4 |
'd' |
double |
float |
8 |
collections.namedtuple
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
- 返回一个新的元组子类,名为 typename 。这个新的子类用于创建类元组的对象,可以通过字段名来获取属性值,同样也可以通过索引和迭代获取值
- 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串
- 存放在对应字段里的数据要以一串参数的形式传入到构造函数中(注意,元组的构造函数却只接受单一的可迭代对象)
- 可以通过字段名或者位置来获取一个字段的信息
1 | import collections |
namedtuple 专有属性
_fields属性是一个包含这个类所有字段名称的元组- 用
_make()通过接受一个可迭代对象来生成这个类的一个实例,它的作用跟Class(*data)是一样的 _asdict()把具名元组以collections.OrderedDict的形式返回
类
属性与实例化
1 | class MyClass: |
类的属性引用: obj.name,类无 name 属性时,引发 AttributeError
类的实例化: x = MyClass()
构造函数
当定义了 __init__()时,类的实例化操作会自动为新创建的类实例发起调用 __init__()
init 函数还可以提供额外参数,例如
1 | def __init__(self): |
实例对象
实例对象的唯一操作是属性引用;有两种有效的属性名称:数据属性和方法
实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法
如果同样的属性名称同时出现在实例和类中,则属性查找会优先选择实例
1 | class MyClass: |
方法的第一个参数常常被命名为 self。 这也不过就是一个约定: self 这一名称在 Python 中绝对没有特殊含义
继承
1 | class Base: |
isinstance(obj, class) 仅会在 obj.__class__ 为 class 或某个派生自 class 的类时为 True
issubclass(classA, classB) 在 classA 为 classB 的子类是为 True
多重继承
class Derived(Base1, Base2, ...)
从父类所继承属性的操作是深度优先、从左至右的,当层次结构中存在重叠时不会在同一个类中搜索两次
如果某一属性在 DerivedClassName 中未找到,则会到 Base1 中搜索它,然后(递归地)到 Base1 的基类中搜索,如果在那里未找到,再到 Base2 中搜索,依此类推
真实情况比这个更复杂一些;方法解析顺序会动态改变以支持对 super() 的协同调用。
这种方式在某些其他多重继承型语言中被称为后续方法调用,它比单继承型语言中的 super 调用更强大。
特殊属性
| 属性 | 说明 |
|---|---|
__init__ |
构造函数 |
__next__ |
从容器中返回下一项 |
__iter__ |
返回迭代器对象本身 |
__dict__ |
一个字典或其他类型的映射对象,用于存储对象的(可写)属性 |
__getitem__ |
调用此方法以实现 self[key] 的求值 |
__getattr__ |
此方法应当返回(找到的)属性值或是引发一个 AttributeError 异常 |
__del__ |
析构函数 |
__call__ |
此方法会在实例作为一个函数被“调用”时被调用 |
__class__ |
类实例所属的类 |
__bases__ |
由类对象的基类所组成的元组 |
__name__ |
类、函数、方法、描述器或生成器实例的名称 |
__repr__ |
输出一个对象的“官方”字符串表示。如果可能,这应类似一个有效的 Python 表达式,能被用来重建具有相同取值的对象 |
__str__ |
生成一个对象的“非正式”或格式良好的字符串表示;内置类型 object 所定义的默认实现会调用 object.__repr__() |
__bool__ |
调用此方法以实现真值检测以及内置的 bool() 操作 |
1 | class MyClass: |
ast - 抽象语法树
ast 模块帮助 Python 程序处理 Python 语法的抽象语法树
节点与函数
ast.AST AST 节点类的基类
ast.parse() 把源码解析为AST节点
ast.unparse() 反解析为字符串
1 | import ast |
ast.NodeTransformer
NodeTransformer 将遍历抽象语法树并使用 visitor 方法的返回值去替换或移除旧节点。
如果 visitor 方法的返回值为 None , 则该节点将从其位置移除,否则将替换为返回值。当返回值是原始节点时,无需替换
1 | import ast |
Beautiful Soup
Beautiful Soup 是第三方库,使用前需安装(bs4)
Beautiful Soup 用于从 HTML 或 XML 文件中提取数据
1 | from bs4 import BeautifulSoup |
json, yaml 模块
yaml 不属于 python 标准库,需安装 pyyaml
1 | import json |
json 命令行工具
python -m json.tool 读取标准输入,验证 json 并美化输出
logging 日志库
记录器对象 logging.Logger
1 | import logging |
日志级别
| 级别 | 数值 |
|---|---|
| CRITICAL | 50 |
| ERROR | 40 |
| WARNING | 30 |
| INFO | 20 |
| DEBUG | 10 |
| NOTSET | 0 |
处理器对象 logging.Handler
1 | handler = logging.FileHandler('output.log') |
格式器对象 logging.Formatter
1 | import logging |
requests - http 库
requests 不是 Python 标准库,使用前需安装
1 | import requests |
sqlite3
Python 内置了 sqlite3 数据库的接口
1 | import sqlite3 |
url 处理模块
1 | urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) |
1 | from urllib import request |