0%

Python-文件操作

使用 Python 对各种文件类型进行操作的相关实践。如:

  • csv:【标准库】支持逗号分隔值格式直接读取和写入文件,一般用于数据库或 excel。
    • csvkit:用于转换和操作 CSV 的工具。
  • XML:XML 格式解析。
    • xmltodict:致力于将 XML 变得像 JSON。
  • json:【标准库】json 编码与解码器
  • pickle:【标准库】Python 特有的序列化对象的标准方式。
  • BSON:short for Binary JSON:JSON 的二进制序列化编码格式
  • pyyaml:yaml 格式文件操作
  • struct:【标准库】处理不定长度的二进制记录格式
  • io:【标准库】处理流的核心工具
  • shelve:【标准库】Python 对象持久化。简单的数据存储方案。
  • base64:【标准库】Base16, Base32, Base64, Base85 数据编码
  • chardet:字符编码探测器:对文本、网页、XML 的编码格式检测,支持中文、日文、韩文等多种语言
  • ConfigParser:【标准库】读取配置文件 ini 的包。
  • markdown :markdown 工具,如 md 转 html
  • xlwings:【优先考虑 pandas】读与改 excel,与 matplotlib 及 pandas 无缝连接,可调用 excel 的 vba
  • tablib:方便地处理表格类型数据。支持导出:Excel、 JSON、 YAML、 Pandas DataFrames、 HTML、 TSV、 OSD、 CSV、 DBF 等格式
  • aiofiles:文件异步操作
  • mimetypes:标准库,将文件名映射为 MIME 类型。
  • python-docx:读写 docx
  • demjson:javascript 的 json 字符串转 python 的字典

概述

计算机常见文件格式一览

  • 参考资料:Manjaro 用户主目录下 .dir_colors
1
2
3
4
5
6
7
DOS-Style: cmd, exe, com, bat, sh, csh, btm
文档文件: txt, csv, json, sql, pdf, tex, doc, log, yml, patch, diff, ps
图片文件: jpg, jpeg, gif,bmp, png, psd, tif, tiff, svg, webm, xcf ,pbm ,pgm ,ppm ,tga ,xbm ,xpm ,mng ,vob ,nuv ,asf ,fli ,gl ,dl ,xwd ,yuv ,cgm ,emf
视频文件: mp4, flv, mov, m4v, avi, rm, rmvb,mpeg,
音频文件: mp3, wav, wmv,aac, au, flac, m4a, midi, mpc, ogg, mid, mka, ra,
压缩包: zip, tar, 7z, rz, tgz, arc, gz, xz, bz, bz2, tz, deb, rpm, jar, war, sar, rar, cab, arj, taz ,lha ,lz4 ,lzh ,lzma ,tlz ,txz ,tzo ,t7z ,z ,Z ,dz ,lrz ,lz ,lzo ,tbz ,tbz2 ,alz ,ace ,zoo ,cpio
MIME_Types_and_File_Extensions: axv, anx, ogv, ogx, axa, oga, spx, xspf

配置文件

配置文件:用于参数设置,不改变源码的情况下改变程序的运行。ini, cfg, conf, 甚至 txt 的 text 文本文档

  • 可移植、独立于平台
  • but,配置文件的末路是 .pyconfig.py
1
2
3
4
# 首选
config.py
config.ini
config.yaml
  • Yaml:以数据为中心
    • 空格易出错,可注释,数据格式多样
  • json
    • 应用于:存储程序运行过程中产生的配置
    • 可读性强,不支持注释
  • ini
    • 应用于:经常阅读与编写的配置文件,如命令行程序的配置文件。

ini

  • 节:[ ]:section
    • 默认节(DEFAULT),可省略
  • 键值对:key-value:options
1
2
3
4
5
6
7
8
9
[db]
db_host = 127.0.0.1
db_port = 69
db_user = root
db_pass = root
host_port = 69
[concurrent]
thread = 10
processor = 20

数据类型序列化

pickling:序列化:持久化:将对象如字符串、列表、字典从内存中变成可存储或可传输的过程。
unpickling:反序列化:变量内容从序列化的对象重新读到内存里

  • 序列化对象:序列化后,可将序列化后的内容写入磁盘,或进行网络传输
    • 解决内存中对象的持久化与传输问题
      • 原生类型:布尔值,整数,浮点数,复数,字符串,字节,None。
      • 原生类型的容器:元组,字典和集合
      • 函数,类,类的实例
    • txt:纯文本,with open r, w, a, b + 模式的直接读写
    • CSV:逗号分隔值
    • JSON:键值对
    • SQL:数据库文件

CSV

csv:【标准库】支持逗号分隔值格式直接读取和写入文件,一般用于数据库或 excel。

csvkit:用于转换和操作 CSV 的工具。

CSV:Comma Separated Values:逗号分隔值:文本形式的二维表,每一行为一条记录,第条记录的字段数量一样,字段间以逗号分隔

python:二维数组

第一行为表头,用于说明每个字段的名称和意义。

1
2
3
id,name,gender,age
1,chen,male,18
2,zhang,female,22

基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
import csv
with open('eggs.csv', newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in spamreader:
print(', '.join(row))


import csv
with open('eggs.csv', 'w', newline='') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

XML

XML:XML 格式解析。

xmltodict:致力于将 XML 变得像 JSON。

  • 不优雅的文件,OUT
  • XML is crap. Really. There are no excuses. XML is nasty to parse for humans, and it’s a disaster to parse even for computers. There’s just no reason for that horrible crap to exist.–Linus Torvalds.
1
2
3
<server>
<port>8080</port>
</server>
1
2
3
xml.etree.ElementTree
xml.dom # DOM:将整个 XML 读入内存,解析为树,用较多内存,解析慢,可任意遍历树的节点。
xml.sax # SAX:流模式,边读边解析,占用内存小,优先考虑

JSON

json:【标准库】json 编码与解码器

JSON:JavaScript Object Notation:JavaScript 对象表示法:轻量级文本数据存储与交换格式,应用程序在网络通信的首选协议格式

  • 用于 web 上数据交换的最广泛使用的数据格式。
  • int/str/list/tuple/dict 类型
  • 作用:文本方式展示结构化数据,常用于 HTTP 下的数据传输。
  • 优点:简单好用、跨平台
  • 数据结构:
    • 对象:键值对
    • 数组
  • " " 内为属性名或值,: 后接前者的值。
  • JSON 官网最新规范规定“键”或者“值”都需要用双引号来表示。
    • 键值对:对象:{}
    • 值的有序列表:数组:[]
  • 简洁清晰的层次结构:
    • 易于阅读与编写, 结构符合程序员阅读习惯
    • 数据为键值对形式,逗号分隔,
    • 大括号保存对象,方括号保存数组
    • None,bool,int,float,和 str,当然也包含字典,列表和元组.
  • 易于给各种编程语言使用:
    • 与 javascript 天然兼容,无需解析,直接使用
    • 易于机器解析与生成,易于转化为数据结构
  • 轻量级数据交换格式:比传统的 xml 更小巧,传输省流量
  • json 文件里的是字符串,utf-8 编码
  • 带 s 的方法是数据类型间的转化 str <–> dict,不带 s 的都是数据与文件的转化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"Students": [
{
"name": "Chen",
"age": 18,
"class": "Computer Science And Technology"
},
{
"name": "Zhang",
"age": 16
}
],
"array": [1, 2, 3],
"boolean": true,
"color": "#82b92c",
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}

数据类型

  • 所有的键都是字符串
JSON 类型Python 类型
{},objectdict
[],arraylist
“string”,字符串,string(必须双引号)str
1234.56,数值,numberint 或 float
true/false,布尔类型True/False
null,空值None

Python 字典

1
2
3
4
5
6
{
"id": 1,
"name": "chen",
"genger": "male",
"age": 18
}

dumps+loads+dump+load

json.dumps(s, default=lambda obj: obj.__dict__)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import json

dic = {'a': 1, 'b': 2, 'c': 3, 'dda': {'name': 'chen'}}
js = json.dumps(dic, sort_keys=True, indent=4, separators=(',', ':'))
print(js)


json_str =
json.loads(json_str, object_hook=dict2student) #反序列化的`Student`实例对象
import json
dict_stu={"age": 20, "score": 88, "name": "Bob"}
str_stu=json.dumps(dict_stu) # dumps:数据类型(字典)转字符串,返回 str
# 双引号,None 变 null,True 变 true

str_json_stu='{"name":"chen","age":18,"name": "Bob"}'
dict_json_stu = json.loads(str_json_stu) # loads:字符串转数据类型
print(dict_json_str['name'])

with open("test.json","w") as f:
json.dump(dict_json,f) # dump:直接写入文件
with open("test.json","r") as f:
dict_json=json.load(f) # load:从文件读取 json 字符串并反序列化

遇到的问题

ensure_ascii

如果无任何配置,或者说使用默认配置,输出的会是 ASCII 字符,而不是真正的中文,这是因为 json.dumps 序列化时对中文默认使用的 ASCII 编码

1
2
3
4
>>> print(json.dumps('中国'))
"\u4e2d\u56fd"
>>> print(json.dumps('中国',ensure_ascii=False))
"中国"

pickle

pickle:【标准库】Python 特有的序列化对象的标准方式。

  • 强大而不通用
  • 优点:强大,支持所有的 Python 类型,如函数与类,保存为 bytes 类型,再反序列化为 Python 类型
  • 缺点:
    • 只能用于 Python,且不同版本的 Python 操作出来的可能不兼容 ,存储数据占空间大
      • pickle会基于你加载的类对象对数据进行对象化,但它把类对象的路径也打包了进去,解析时需要对应的类在对应目录、文件里
    • 不安全:反序列化别人精心设计的数据时,可能被动执行任意代码。
      • 只unpickle你信任的数据
    • 故 OUT

dumps+loads

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pickle

# 将obj对象 序列化为 bytes字节对象
pickle.dumps(obj_name)

# 从 bytes字节对象 中读取 一个反序列化对象,并返回
# 反序列化数据类型不变
pickle.loads(bytes_object)

# 例
def test():
print('ok')
data = pickle.dumps(test)
print(data)
b'\x80\x03c__main__\ntest\nq\x00.' #序列化之后的函数
type(data) # <class 'bytes'> #因为是 byte 类型 写入文件时候要'wb'

dump+load

1
2
3
4
5
6
7
8
9
import pickle

# dump:object 序列化存放 file,将数据通过特殊的形式转换为只有 python 语言认识的字符串,并写入文件、
pickle.dump(obj,file,[,protocol])

# load:file 对象序列化读出。从数据文件中读取数据,并转换为 python 的数据结构
# 必填参数 file 必须以二进制可读模式打开,即“rb”,其他都为可选参数
pickle.load(file,*,fix_imports=True, encoding="ASCII", errors="strict")

异常

  • PickleError:封装和拆封时出现的异常类,继承自 Exception
  • PicklingError:遇到不可封装的对象时出现的异常,继承自 PickleError
  • UnPicklingError:拆封对象过程中出现的异常,继承自 PickleError

测试

1
2
3
4
5
6
7
8
9
# 小文件 10ms级,具体取决于大小与磁盘
with open('test.pkl', 'wb') as f:
pickle.dump(anno_list, f)
print(f'完成保存到本地用时: {time.time()-start_time}')

with open('test.pkl', 'rb') as f2:
new_anno_list = pickle.load(f2)
print(len(new_anno_list))
print(f'完成加载本地用时: {time.time()-start_time}')

BSON

BSON:short for Binary JSON:JSON 的二进制序列化编码格式

  • 特点:
    • 轻量级:Lightweight
    • 可遍历:Traversable
    • 高效性:Efficient

YAML

pyyaml:yaml 格式文件操作

概述

YAML:YAML Ain’t a Markup Language:YAML 不是一种标记语言,
yaml:/ˈjæməl/:可读性高、用来表达数据序列化的格式

  • YAML 是针对所有编程语言的人性化数据序列化标准,快成为 Linux 下的主流配置文件的文件类型,but 格式要求过于严格。
  • 以数据为中心,比 json、xml 更适合做配置文件
  • 【OUT】:相同内容,采用 yaml、json 文件,load 1000 次,yaml 需要 1.117 秒,json 只需要 0.005 秒
  • 特点:
    • 优点:
      • 数据格式多样
      • 支持注释
      • 易读
    • 缺点:
      • 一个空格可能引发惨案
      • 致命缺点:对于相同数据类型的数据,表现形式不一样,虽然 20.2 可能是 float 或 str,但这种特性导致了不稳定性。
1
2
3
4
5
6
当前版本号:
- 20.1.1
- 20.1.2
- "20.2"
- 20.2.1
- 21.0-pre1
  • 区分大小写,字符串不需引号
  • 空格缩进表层级,空格数不定,相同层级元素左侧对齐即可
  • 注释为 #
  • 纯量 (scalars):单个的、不可再分的值(如:字符串、bool 值、整数、浮点数、时间、日期、null 等)
    None 值可用 null 可 ~ 表示
1
2
3
4
5
6
7
8
9
10
11
12
13
# 纯量
s_val: name # 字符串:{'s_val': 'name'}
spec_s_val: "name\n" # 特殊字符串:{'spec_s_val': 'name\n'
num_val: 31.14 # 数字:{'num_val': 31.14}
bol_val: true # 布尔值:{'bol_val': True}
nul_val: null # null 值:{'nul_val': None}
nul_val1: ~ # null 值:{'nul_val1': None}
time_val: 2018-03-01t11:33:22.55-06:00 # 时间值:{'time_val': datetime.datetime(2018, 3, 1, 17, 33, 22, 550000)}
date_val: 2019-01-10 # 日期值:{'date_val': datetime.date(2019, 1, 10)}
name: chen # 对象:键值对集合
list: # 数组
- student1 # 空格分隔
- student2

基本使用

  • 扩展名:.yaml.yml

  • 大小写敏感

  • 使用空格的缩进:只能用空格表缩进,同一层级左侧对齐

  • key: value,注意 冒号后面必须有一个空格

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # person.yml # 单行注释,不支持多行注释
    person:
    last-name: zhangsan
    age: 20
    birth: 2017/12/15
    boss: false
    maps:{key1:value1,key2:value2}
    lists:[a,b,c]
    dog:
    name: dog
    age: 1
  • 数据结构:

    • 字面量(数字、字符串、布尔值):单个的、不可再分的值
      • k: v,字符串不用加引号

      • 双引号不会转义特殊字符,单引号会转义特殊字符

      • name: chen
        age: 18
        isStudent: false
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10

        - **数组**:一组按次序排列的值,又称为序列(sequence) / 列表(list)
        - 可多行或单行

        ```yaml
        names:
        - chen
        - zhang
        - li
        age:[18,19,20]
    • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
1
2
3
4
5
6
#多行结构
friend:
name:zhangsan
age:20
#单行结构
friend:{name:zhangsan,age:20}
1
2
3
4
# 加载
d = yaml.load(f,Loader=yaml.FullLoader)
# 写入 unicode
yaml.dump(msg_dict,f,allow_unicode=True)

struct

struct:【标准库】处理不定长度的二进制记录格式

  • 如 不使用 zipfile 即可循环遍历一个 zip 文件的所有头信息。
  • Pack 代码 "H""I" 分别代表两字节和四字节无符号整数。"<" 代表它们是标准尺寸的小尾型字节序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct.pack()

struct.unpack()


import struct

with open('myfile.zip', 'rb') as f:
data = f.read()

start = 0
for i in range(3): # show the first 3 file headers
start += 14
fields = struct.unpack('<IIIHH', data[start:start+16])
crc32, comp_size, uncomp_size, filenamesize, extra_size = fields

start += 16
filename = data[start:start+filenamesize]
start += filenamesize
extra = data[start:start+extra_size]
print(filename, hex(crc32), comp_size, uncomp_size)

start += extra_size + comp_size # skip to the next header

IO

io:【标准库】处理流的核心工具

shelve

shelve:【标准库】Python 对象持久化。简单的数据存储方案。

  • shelve 模块以类似字典的方式将 Python 对象持久化,它依赖于 pickle 模块,但比 pickle 用起来简单。当我们写程序的时候如果不想用关系数据库那么重量级的程序去存储数据,可以简单地使用 shelve。shelve 使用起来和字典类似,也是用 key 来访问的,键为普通字符串,值则可以是任何 Python 数据类型,并且支持所有字典类型的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
shelve.open(filename, flag='c', protocol=None, writeback=False)

shelve.close()

>>> import shelve
>>> d = shelve.open("d:\\1")
>>> d['list'] = [0, 1, 2] # 正常工作
>>> d['list']
[0, 1, 2]
>>> d['list'].append(3) # 给它添加个3
>>> d['list'] # 无效!d['list']还是[0, 1, 2]!
[0, 1, 2]

# 这种情况需要使用中间变量 或writeback=True
temp = d['list']
temp.append(3) # 修改数据
d['list'] = temp # 再存回去

如果我们想让 shelve 去自动捕获对象的变化,应该在打开 shelve 文件的时候将 writeback 参数设置为 True。此时,shelve 会将所有数据放到缓存中,并接收后续对数据的修改操作。最后,当我们 close() 的时候,缓存中所有的对象一次性写回磁盘内。

writeback=True 有优点也有缺点。优点是可以动态修改数据,并减少出错的概率,让对象的持久化对用户更加的透明。但也有很大的缺点,在 open() 的时候会增加额外的内存消耗,并且当 close() 对象的时候会将缓存中的每一个细节都写回到文件系统,这也会带来额外的等待时间和计算消耗,因为 shelve 没有办法知道缓存中哪些对象修改了,哪些对象没有修改,所有的对象都必须被写入。

base64

base64:【标准库】Base16, Base32, Base64, Base85 数据编码

  • 用 64 个字符来编码任意二进制文件如 exe、jpg、pdf 等
    • 64 个字符:[A-Za-z0-9{+}{/}]
    • 对二进制数据进行处理,每 3 个字节一组,一共是 3x8=24bit,划为 4 组,每组正好 6 个 bit:这样我们得到 4 个数字作为索引,然后查表,获得相应的 4 个字符,就是编码后的字符串。
    • 所以,Base64 编码会把 3 字节的二进制数据编码为 4 字节的文本数据,长度增加 33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。
      如果要编码的二进制数据不是 3 的倍数,最后会剩下 1 个或 2 个字节怎么办?Base64 用 \x00 字节在末尾补足后,再在编码的末尾加上 1 个或 2 个 = 号,表示补了多少字节,解码的时候,会自动去掉。
    • 由于标准的 Base64 编码后可能出现字符 +/,在 URL 中就不能直接作为参数,所以又有一种 “url safe” 的 base64 编码,其实就是把字符 +/ 分别变成 -_
  • 通过查表的编码方法,不能用于加密(即使是自定义的编码表也不行)
  • 用处:
    • 小段内容的编码,如数据证书签名、Cookie 的内容等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
str_ = 'Hello World' # 原始数据
str_decode=base64.b64encode(pickle.dumps(str)).decode() # 加密
b = pickle.loads(base64.b64decode(a.encode())) # 解密

base64.b64encode('Hello World'.encode('utf'))

import base64
with open("test.jpg",'rb') as f:
c=f.read()
x=base64.encodestring(c)
base64.b64encode(b'binary\x00string') #b'YmluYXJ5AHN0cmluZw=='
base64.b64decode(b'YmluYXJ5AHN0cmluZw==') #b'binary\x00string'

# 由于标准的 Base64 编码后可能出现 + 与 / ,在 URL 中不能直接作为参数,所以有 usr_safe 的 base64 编码,将 + 与 / 变成 - 与 _
base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
# b'abcd++//'

base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
# b'abcd--__'
base64.urlsafe_b64decode('abcd--__')
# b'i\xb7\x1d\xfb\xef\xff'

chardet

chardet:字符编码探测器:对文本、网页、XML 的编码格式检测,支持中文、日文、韩文等多种语言

  • Unicode 有 strbytes 两种数据类型,可通过 encode()decode() 方法转换,但是,在不知道编码的情况下,对 bytesdecode() 不好做。
  • 对于未知编码的 bytes,要把它转换成 str,需要先“猜测”编码。猜测的方式是先收集各种编码的特征字符,根据特征字符判断,就能有很大概率“猜对
1
2
3
4
5
6
import chardet
chardet.detect(b'hello')
# {'encoding': 'ascii', 'confidence': 1.0, 'language': ''} # ascii,100%准确率
data = '离离原上草,一岁一枯荣'.encode('gbk')
chardet.detect(data)
# {'encoding': 'GB2312', 'confidence': 0.7407407407407407, 'language': 'Chinese'}

ConfigParser

ConfigParser:【标准库】读取配置文件 ini 的包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import configparser
conf = configparser.ConfigParser() # 实例化一个对象
conf.read("test.ini", encoding="utf-8")
# 查
print(conf.sections()) # 获取所用的 section 节点
print(conf.options("db")) # db section 下的所有 options
print(conf.get("db", "db_host"))
# r1 = config.getint("db", "k1") #将获取到值转换为 int 型
# r2 = config.getboolean("db", "k2" ) #将获取到值转换为 bool 型
# r3 = config.getfloat("db", "k3" ) #将获取到值转换为浮点型
r = config.items("db")
#[('db_host', '127.0.0.1'), ('db_port', '69'), ('db_user', 'root'), ('db_pass', 'root'), ('host_port', '69')]
# 改,修改某个 option 的值,如果不存在该 option 则会创建
config.set("db", "db_port", "69") #修改 db_port 的值为 69
config.write(open("ini", "w+"))
config.has_section("section") #是否存在该 section
config.has_option("section", "option") #是否存在该 option
if not config.has_section("default"): # 检查是否存在 section
config.add_section("default")
if not config.has_option("default", "db_host"): # 检查是否存在该 option
config.set("default", "db_host", "1.1.1.1")
config.write(open("ini", "w"))
#向 ini 中添加内容
conf.add_section("Account")
conf.set("Account","title","1")
conf.write(open("test_cfg.ini","w+"))
# 删
config.remove_section("default") #整个 section 下的所有内容都将删除
config.write(open("ini", "w"))
以下的几行代码只是将文件内容读取到内存中,进过一系列操作之后必须写回文件,才能生效。
config.write(open("ini", "w"))

写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import configparser

config = configparser.ConfigParser()

# 用法 1:将 section 的键值对写入到字典中
config["DEFAULT"] = {
"Country": "China",
"Max_Iter": "2",
}

# 用法 2,逐级添加值对
config["section_1"] = {}
config["section_1"]["a"] = "2"

# 用法 3:将初始化的 section 先赋值给一个变量,再添加其他键值对
config["section_2"] = {}
section2 = config["section_2"]
section2["b"] = "2"

config['DEFAULT']['ForwardX11'] = 'yes'

with open("example.ini", "w") as fp:
config.write(fp)

读取

1
2
3
4
5
6
7
8
9
10
11
import configparser

config=configparser.ConfigParser()
config.read('test.ini')
# section
sections=config.sections()
print(sections)

print(config["DEFAULT"]["country"])
print(config["section_1"]["a"])

  • 数据类型:
    • 在解析配置文件时,不区别类型,value 视为字符串
    • 整型:getint
      • 不能用 getint 去取 float,会报错
    • 浮点型:getfloat
    • 布尔型
      • 布尔型:’yes’/‘no’,’on’/‘off’,’true’/‘false’ 和 ‘1’/‘0’ 等来设定
      • 通过 getboolean 函数读取对应的参数
  • 默认值:
    • top.get("max_iter", fallback=4)
  • 插值:通过 ${section:option} 的方式调用其他 section 的参数
1
2
3
4
5
6
[DEFAULT]
country = China
max_iter = 2
a = true
b = off
c = 1
1
2
3
4
5
6
7
8
print(config["DEFAULT"].getboolean("a"))
print(config["DEFAULT"].getboolean("b"))
print(config["DEFAULT"].getboolean("c"))

# 输出
True
False
True

markdown

markdown :markdown 工具,如 md 转 html

mistune

mistune:快速且强大的 Python 解析库

  • 特点:
    • 性能
    • 灵活性:轻松扩展和定制
    • 支持标准的 Markdown 语法,可通过插件扩展支持更多的功能(数学公式、高亮代码、自定义渲染等)
  • 问题:无法解析列表后的多个空行

基本使用

  • Markdown 解析
1
2
3
4
5
6
import mistune

markdown = mistune.create_markdown()
text = "# Hello, Markdown!\n\nThis is a **Markdown** document."
html = markdown(text)
print(html)
  • HTML 渲染:将 markdown 转换为 HTML
1
2
3
4
5
6
7
8
9
import mistune

markdown = mistune.create_markdown()

with open('example.md', 'r') as file:
text = file.read()

html = markdown(text)
print(html)
  • 插件支持
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 代码高亮
import mistune
from mistune.plugins import plugin_codehilite

markdown = mistune.create_markdown(plugins=[plugin_codehilite])
text = "```python\nprint('Hello, world!')\n```"
html = markdown(text)
print(html)

# 数学公式
import mistune
from mistune.plugins import plugin_math

markdown = mistune.create_markdown(plugins=[plugin_math])
text = "This is a math formula: $E=mc^2$"
html = markdown(text)
print(html)
  • 自定义渲染
1
2
3
4
5
6
7
8
9
10
11
import mistune

class CustomRenderer(mistune.HTMLRenderer):
def heading(self, text, level):
return f'<h{level} class="custom-heading">{text}</h{level}>\n'

renderer = CustomRenderer()
markdown = mistune.create_markdown(renderer=renderer)
text = "# Custom Heading\n\nThis is a custom heading example."
html = markdown(text)
print(html)
  • mistune:Streamlit 也是用的这个
  • Mistune 提供了插件机制,允许用户在解析过程中添加自定义行为。可以通过插件来扩展 Markdown 的功能,例如添加新的语法支持或修改现有的解析逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

from mistune import HTMLRenderer, create_markdown

class CustomRenderer(HTMLRenderer):
def heading(self, text, level):
return f'<h{level} style="color:blue;">{text}</h{level}>'

# 使用自定义渲染器创建 Markdown 解析器
markdown = create_markdown(renderer=CustomRenderer())

md_text = "# Custom Heading"

html = markdown(md_text)

print(html) # 输出的标题将使用蓝色

import mistune

# 创建一个 Markdown 解析器实例
markdown = mistune.create_markdown()
# Markdown 文本
md_text = """
# 标题
这是一个段落,其中包含**加粗文本**和*斜体文本*。
- 列表项 1
- 列表项 2
[链接文本](http://example.com)
"""
# 将 Markdown 转换为 HTML
html = markdown(md_text)
print(html)

tomd:html 转 markdown
Mistune 是一个快速、轻量级且高度可扩展的 Markdown 解析器,使用纯 Python 实现。它以其高性能和灵活性著称,适合需要自定义渲染和扩展功能的应用场景。

主要特点

  • 高性能: Mistune 在解析速度上表现非常优异,适合对性能有较高要求的项目。
  • 高度可扩展: 提供了自定义渲染器和插件机制,用户可以轻松定制 Markdown 解析的行为。
  • 符合 CommonMark 标准: 默认情况下,Mistune 遵循 CommonMark 标准,确保 Markdown 文本的一致性解析。
  • 轻量级: 设计简单,易于集成和使用。

excel

xlwings:【优先考虑 pandas】读与改 excel,与 matplotlib 及 pandas 无缝连接,可调用 excel 的 vba

  • 如无必要,勿增实体。尽量不增加新的模块,excel 即二维数组,用 pandas
1
2
3
4
5
6
7
8
9
# 简单示例,对 excel 有需求上 pandas
import xlwings as xw
wb=xw.Book("test.xlsx")
sht = wb.sheets["sheet1"]
wb.fullname
sht.name
sht.range('A1').value="chen"
sht.range('A1').value
sht.range('A1').clear()

tablib

tablib:方便地处理表格类型数据。支持导出:Excel、 JSON、 YAML、 Pandas DataFrames、 HTML、 TSV、 OSD、 CSV、 DBF 等格式

1
2
3
4
5
6
7
8
9
10
11
12
import tablib
dataset1 = tablib.Dataset()
# 创建 1
dataset1.headers={'id','name','age','gender'}
dataset1.append(['1','chen','25','male']) # 增
# 创建 2
header2 = ['id','name','password']
data = [
['1','杨鹏','123'],
['2','代松柏','567'],
]
dataset2 = tablib.Dataset(headers=header2,*data)

aiofiles

aiofiles:文件异步操作

mimetypes

mimetypes:标准库,将文件名映射为 MIME 类型。

filetype:第三方库,还不如 mimetypes,.md 的也测不出来也就算了,.ppt 的都不行

MIME:Multipurpose Internet Mail Extensions:多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

1
2
import mimetypes
print(mimetypes.guess_type(file_path))

Office

python-docx:读写 docx
python-pptx:读写 pptx
xlrd:读取 excel 的库
xlwt:写 excel 的库
xlutils:操作修改 excel 文件方法的库(基于 xlrd 与 xlwt,先复制一个副本操作后保存)
xlsxwriter:创建 Excel XLSX 文件的 Python 模块

1
2
3
4
import docx
f=docx.Document('test.docx') # Document 对象,即一个 word 文档
len(f.paragraphs) # Paragraph 对象,一个大段董路
f.paragraphs[2].text
1
2
3
4
5
6
7
8
9
10
11
12
13
from pptx import Presentation
prs=Presentation('./test.pptx')


import pandas as pd
import docx
import pptx


word = docx.Document(file)
excel = pd.read_excel(file)
ppt = pptx.Presentation(file)

遇到的问题

  • xlrd.biffh.XLRDError: Excel xlsx file; not supported
  • 解决方案:原因是新版的 xlrd 不支持 xlsx 文件的读入,需安装老版本:
    pip3 install xlrd==1.2.0

python-pptx

python-pptx:python 操作 ppt 的库

概述

常识

  • 基本概念
    • Slide:幻灯片,指 ppt 中的一页
    • Shape:方框:指 ppt 中的一个块,如形状、文本框
    • Run:文字块,一般为较少字符
    • Paragraph:段落,通常有序号

操作

1
2
3
from pptx import Presentation
from pptx.util import Inches,Pt
ppt=Presentation()

demjson

demjson:javascript 的 json 字符串转 python 的字典

  • 用处:用来解析 json 库解析不了的非标准 json 格式字符串 {0:"a",1:"b",2:"c",3:"d"},key 没有引号,只有值有引号
1
2
3
import demjson
demjson.decode(str_,encoding='utf-8') # 将 json 字符串变成 json 对象
demjson.encode(obj,encoding='utf-8') # 将对象转换为 json 字符串

PyMuPDF

#最佳实践

pypdf2

pypdf2:对 pdf 文件的基本操作

  • 能够拆分、合并、裁剪和转换 PDF 文件的页面。它还可以向 PDF 文件添加自定义数据、查看选项和密码。它可以从 PDF 中检索文本和元数据,也可以将整个文件合并在一起。
1
2
3
4
5
6
7
8
9
10
11
from PyPDF2 import PdfFileMerger
import os

file_list = [file for file in os.listdir() if file.endswith('.pdf')]
merger = PdfFileMerger()
for file_path in file_list:
merger.append(open(file_path, 'rb'))

with open('newfile.pdf', 'wb') as f_out: # 输出文件为newfile.pdf
merger.write(f_out)

fpdf

fpdf:PDF 工具库

1
pip install feather-format

feather

  • 相比于csv、pickle,占用体积最小、速度最快
给博主来一杯卡布奇诺