Python基础模块
# 1.webbrowser模块
python的webbrowser
模块支持对浏览器进行一些操作,对于爬虫来说是比较基础的知识点
1.主要有以下三个方法:
webbrowser.open(url, new=0, autoraise=True)
webbrowser.open_new(url)
webbrowser.open_new_tab(url)
import webbrowser as web
web.open(‘http://www.baidu.com’,new=0,autoraise=True) #new:0/1/2 0:同一浏览器窗口打开 1:打开浏览器新的窗口,2:打开浏览器窗口新的tab
#autoraise=True:窗口自动增长
web.open_new(‘http://www.baidu.com’)
web.open_new_tab(‘http://www.baidu.com’)
2
3
4
5
2.指定浏览器对象打开
web.get(name):获取打开的浏览器对象,name为空,则打开默认的浏览器,name为浏览器名称
直接打开则会报错,需要注册浏览器对象
web.register():注册浏览器类型
import webbrowser as web
firefoxpath = 'D:\\firefox\\firefox.exe'
web.register('firefox', None, web.BackgroundBrowser(firefoxpath))
web.get('firefox').open('www.baidu.com')
2
3
4
而webbrowser.get()方法可以获取到系统浏览器的操作对象。
webbrowser.register()方法可以注册浏览器类型,而允许被注册的类型名称如下:
Type Name Class Name Notes
'mozilla' Mozilla('mozilla')
'firefox' Mozilla('mozilla')
'netscape' Mozilla('netscape')
'galeon' Galeon('galeon')
'epiphany' Galeon('epiphany')
'skipstone' BackgroundBrowser('skipstone')
'kfmclient' Konqueror() (1)
'konqueror' Konqueror() (1)
'kfm' Konqueror() (1)
'mosaic' BackgroundBrowser('mosaic')
'opera' Opera()
'grail' Grail()
'links' GenericBrowser('links')
'elinks' Elinks('elinks')
'lynx' GenericBrowser('lynx')
'w3m' GenericBrowser('w3m')
'windows-default' WindowsDefault (2)
'macosx' MacOSX('default') (3)
'safari' MacOSX('safari') (3)
'google-chrome' Chrome('google-chrome')
'chrome' Chrome('chrome')
'chromium' Chromium('chromium')
'chromium-browser' Chromium('chromium-browser')
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
# 2.urllib模块
https://www.liaoxuefeng.com/wiki/1016959663602400/1019223241745024
urllib提供了一系列用于操作URL的功能。
# Get
urllib的request
模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应:
例如,对豆瓣的一个URLhttps://api.douban.com/v2/book/2129650
进行抓取,并返回响应:
from urllib import request
with request.urlopen('http://news-at.zhihu.com/api/4/news/latest') as f:
data = f.read()
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', data.decode('utf-8'))
2
3
4
5
6
7
8
可以看到HTTP响应的头和JSON数据:
Status: 200 OK
Date: Thu, 29 Aug 2019 15:30:57 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 1821
Connection: close
Set-Cookie: tgw_l7_route=7bacb9af7224ed68945ce419f4dea76d; Expires=Thu, 29-Aug-2019 15:45:57 GMT; Path=/
Vary: Accept-Encoding
Etag: "f27bea06ec36624857dc959734aa2727d15df46d"
X-Backend: zhihu-daily-web--28-b991030d-1538061071-8w6wc
X-Backend-Response: 0.003
Server: ZWS
Set-Cookie: _xsrf=uGtc0CtELClNoL0q6IEY0nag22iJB7X7; path=/; domain=zhihu.com; expires=Mon, 14-Feb-22 15:30:57 GMT
Data: {"....."}]}
2
3
4
5
6
7
8
9
10
11
12
13
14
如果我们要想模拟浏览器发送GET请求,就需要使用Request
对象,通过往Request
对象添加HTTP头,我们就可以把请求伪装成浏览器。例如,模拟谷歌浏览器去请求麦课页面:
import urllib.request
import time # 会有时间戳,进行构造
url = 'https://weiban.mycourse.cn/pharos/usercourse/listCourse.do?timestamp='
req = request.Request('http://www.douban.com/')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
with request.urlopen(req) as f:
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', f.read().decode('utf-8'))
2
3
4
5
6
7
8
9
10
11
12
这样豆瓣会返回适合iPhone的移动版网页:
...
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<meta name="format-detection" content="telephone=no">
<link rel="apple-touch-icon" sizes="57x57" href="http://img4.douban.com/pics/cardkit/launcher/57.png" />
...
2
3
4
5
6
# Post
如果要以POST发送一个请求,只需要把参数data
以bytes形式传入。
我们模拟一个微博登录,先读取登录的邮箱和口令,然后按照weibo.cn的登录页的格式以username=xxx&password=xxx
的编码传入:
from urllib import request, parse
print('Login to weibo.cn...')
email = input('Email: ')
passwd = input('Password: ')
login_data = parse.urlencode([
('username', email),
('password', passwd),
('entry', 'mweibo'),
('client_id', ''),
('savestate', '1'),
('ec', ''),
('pagerefer', 'https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F')
])
req = request.Request('https://passport.weibo.cn/sso/login')
req.add_header('Origin', 'https://passport.weibo.cn')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
req.add_header('Referer', 'https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F')
with request.urlopen(req, data=login_data.encode('utf-8')) as f:
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', f.read().decode('utf-8'))
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
如果登录成功,我们获得的响应如下:
Status: 200 OK
Server: nginx/1.2.0
...
Set-Cookie: SSOLoginState=1432620126; path=/; domain=weibo.cn
...
Data: {"retcode":20000000,"msg":"","data":{...,"uid":"1658384301"}}
2
3
4
5
6
7
如果登录失败,我们获得的响应如下:
...
Data: {"retcode":50011015,"msg":"\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef","data":{"username":"example@python.org","errline":536}}
2
3
# Handler
如果还需要更复杂的控制,比如通过一个Proxy去访问网站,我们需要利用ProxyHandler
来处理,示例代码如下:
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
with opener.open('http://www.example.com/login.html') as f:
pass
2
3
4
5
6
7
# 小结
urllib提供的功能就是利用程序去执行各种HTTP请求。如果要模拟浏览器完成特定功能,需要把请求伪装成浏览器。伪装的方法是先监控浏览器发出的请求,再根据浏览器的请求头来伪装,User-Agent
头就是用来标识浏览器的。
# 3. json模块
# 一、概念
- json是一种通用的数据类型,任何语言都认识
- 接口返回的数据类型都是json
- 长得像字典,形式也是k-v
- 其实json是字符串
- 字符串不能用key、value来取值,要先转成字典才可以
- 格式如下:
{
"error_code": 0,#要使用双引号,如果是单引号则运行时会报错,可以上网做在线json格式校验
"stu_info": [
{
"id": 309,
"name": "小白",
"sex": "男",
"age": 28,
"addr": "河南省济源市北海大道32号",
"grade": "天蝎座",
"phone": "18512572946",
"gold": 100
},
{
"id": 310,
"name": "小白",
"sex": "男",
"age": 28,
"addr": "河南省济源市北海大道32号",
"grade": "天蝎座",
"phone": "18516572946",
"gold": 100
}
]
}
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
# 二、json操作
# 1、json串转成字典:
# (1).loads()方法
import json#引用json模块
res=json.loads(s)
print(res)#打印字典
print(type(res))#打印res类型
print(res.keys())#打印字典的所有Key
2
3
4
5
6
- 要先读文件,然后再转换:
f=open('stus.json',encoding='utf-8')
content=f.read()#使用loads()方法,需要先读文件
user_dic=json.loads(content)
print(user_dic)
2
3
4
5
# (2).load()方法
import json
f=open('stus.json',encoding='utf-8')
user_dic=json.load(f)
print(user_dic)
2
3
4
5
# (3)区别
- loads()传的是字符串,而load()传的是文件对象
- 使用loads()时需要先读文件再使用,而load()则不用
# 2、字典转成json串:
- 文件里只能写字符串,但可以把字典转成json串,json串是字符串,可以存到文件里
# (1).dumps()方法
stus={'xiaojun':'123456','xiaohei':'7891','abc':'11111'}
#先把字典转成json
res2=json.dumps(stus)
print(res2)#打印字符串
print(type(res2))#打印res2类型
2
3
4
5
6
- .dumps()方法:把字典转成json串
with open('stus.txt','w',encoding='utf-8' as f:#打开文件
f.write(res2)#在文件里写入转成的json串
2
3
- 使用.dumps()方法前,要先打开文件,再写入:
stus={'xiaojun':'123456','xiaohei':'7890','lrx':'111111'}
res2=json.dumps(stus,indent=8,ensure_ascii=False)
print(res2)
with open('stus.json','w',encoding='utf-8') as f:#使用.dumps()方法时,要写入
f.write(res2)
2
3
4
5
6
# (2)dump()方法
stus={'xiaojun':'123456','xiaohei':'7890','lrx':'111111'}
f=open('stus2.json','w',encoding='utf-8')
json.dump(stus,f,indent=4,ensure_ascii=False)
2
3
4
# (3)区别
- .dump()不需要使用.write()方法,只需要写哪个字典、哪个文件即可;而.dumps()需要使用.write()方法写入
- 如果要把字典写到文件里面的时候,dump()好用;但如果不需要操作文件,或需要把内容存到数据库和Excel,则需要使用**dumps()**先把字典转成字符串,再写入
# (4)dump\dumps参数
- .dumps\dump中使用参数indent,为字符串换行+缩进:
res2=json.dumps(stus.indent=4)
print(res2)#打印字符串
#结果为:
'''
{
"xiaojun": "123456",
"xiaohei": "7891",
"lrx": "hailong",
"tanailing": "111111"
}
'''
2
3
4
5
6
7
8
9
10
11
12
- .dumps\dump中使用参数ensure_ascii,为内容输出为中文:
res2=json.dumps(stus,indent=4,ensure_ascii=False)#为False时内容输出显示正常的中文,而不是转码
print(res2)
2
3
3、不管是dump还是load,带s的都是和字符串相关的,不带s的都是和文件相关的。
# 4.os模块
# 4.1系统操作
os.sep
:主要用于系统路径的分隔符。Windows系统通过是“\”,Linux类系统如Ubuntu的分割符是“/”
os.name
:指示你正在使用的工作平台。Windows是nt
,Linux/Unix用户,它是posix
os.getenv(key)
:读取环境变量,其中key为环境变量的名称,例如path
os.getcwd()
:获取当前的路径
# 4.2判断和path
os.path.exists(path)
:判断文件或者目录是否存在。存在返回True,否则返回False。
os.path.isfile(path)
:判断是否为文件。是文件返回True,否则返回False
os.paht.isdir(paht)
:判断是否为目录。同上
os.path.basename(path)
:返回文件名
os.path.dirname(path)
:返回文件路径
os.path.getsize(path)
:获取文件大小,如果name是目录返回0L
os.path.abspath(path)
:获得绝对路径
os.path.join(path,name)
:链接目录与文件名或目录
# 4.3目录操作-增删改查
os.listdir(path)
:返回指定目录(path)下的所有文件和目录名,就是所有的文件名,按照字典序
os.mkdir()
:创建一个目录,只创建一个目录文件
os.rmdir()
:删除一个空目录,若目录中有文件则无法删除。
os.makedirs(dirname)
:可以生成多层递归目录,如果目录全部存在,则创建目录失败
os.removedirs(dirname)
:可以删除多层递归的空目录,若目录中有文件则无法删除
os.chdir()
:改变当前目录,到指定目录中。
os.rename()
:重命名目录名或者文件名,重命名后的文件名存在,测重命名失败。
# 5.String
方法 | 描述 |
---|---|
string.capitalize() (opens new window) | 把字符串的第一个字符大写 |
string.center(width) (opens new window) | 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 |
string.count(str, beg=0, end=len(string)) (opens new window) | 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
string.decode(encoding='UTF-8', errors='strict') (opens new window) | 以 encoding 指定的编码格式解码 string,如果出错默认报一个 ValueError 的 异 常 , 除 非 errors 指 定 的 是 'ignore' 或 者'replace' |
string.encode(encoding='UTF-8', errors='strict') (opens new window) | 以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace' |
string.endswith(obj, beg=0, end=len(string)) (opens new window) | 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. |
string.expandtabs(tabsize=8) (opens new window) | 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8。 |
string.find(str, beg=0, end=len(string)) (opens new window) | 检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1 |
string.index(str, beg=0, end=len(string)) (opens new window) | 跟find()方法一样,只不过如果str不在 string中会报一个异常. |
string.isalnum() (opens new window) | 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False |
string.isalpha() (opens new window) | 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False |
string.isdecimal() (opens new window) | 如果 string 只包含十进制数字则返回 True 否则返回 False. |
string.isdigit() (opens new window) | 如果 string 只包含数字则返回 True 否则返回 False. |
string.islower() (opens new window) | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
string.isnumeric() (opens new window) | 如果 string 中只包含数字字符,则返回 True,否则返回 False |
string.isspace() (opens new window) | 如果 string 中只包含空格,则返回 True,否则返回 False. |
string.istitle() (opens new window) | 如果 string 是标题化的(见 title())则返回 True,否则返回 False |
string.isupper() (opens new window) | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
string.join(seq) (opens new window) | 以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
string.ljust(width) (opens new window) | 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串 |
string.lower() (opens new window) | 转换 string 中所有大写字符为小写. |
string.lstrip() (opens new window) | 截掉 string 左边的空格 |
string.maketrans(intab, outtab]) (opens new window) | maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 |
max(str) (opens new window) | 返回字符串 str 中最大的字母。 |
min(str) (opens new window) | 返回字符串 str 中最小的字母。 |
string.partition(str) (opens new window) | 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 元 素 的 元 组 (string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string. |
string.replace(str1, str2, num=string.count(str1)) (opens new window) | 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次. |
string.rfind(str, beg=0,end=len(string) ) (opens new window) | 类似于 find()函数,不过是从右边开始查找. |
string.rindex( str, beg=0,end=len(string)) (opens new window) | 类似于 index(),不过是从右边开始. |
string.rjust(width) (opens new window) | 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串 |
string.rpartition(str) | 类似于 partition()函数,不过是从右边开始查找. |
string.rstrip() (opens new window) | 删除 string 字符串末尾的空格. |
string.split(str="", num=string.count(str)) (opens new window) | 以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串 |
string.splitlines(num=string.count('\n')) (opens new window) | 按照行分隔,返回一个包含各行作为元素的列表,如果 num 指定则仅切片 num 个行. |
string.startswith(obj, beg=0,end=len(string)) (opens new window) | 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查. |
string.strip([obj]) | 在 string 上执行 lstrip()和 rstrip() |
string.swapcase() (opens new window) | 翻转 string 中的大小写 |
string.title() (opens new window) | 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) |
string.translate(str, del="") (opens new window) | 根据 str 给出的表(包含 256 个字符)转换 string 的字符,要过滤掉的字符放到 del 参数中 |
string.upper() (opens new window) | 转换 string 中的小写字母为大写 |
string.zfill(width) (opens new window) | 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0 |
string.isdecimal() (opens new window) | isdecimal()方法检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。 |
# 6. Jupyter notebook
# 0.准备
# 安装jupyter
pip install jupyter
# 启动, 命令行直接
jupyter notebook
# 修改启动目录
jupyter notebook --generate-config
c.NotebookApp.notebook_dir = 'd:' # 大约在266行
2
3
4
5
6
7
8
9
# 1.使用
# 1.shell命令
Shell是一种与计算机进行文本交互的方式。
一般来讲,当你正在使用Python编译器,需要用到命令行工具的时候,要在shell和IDLE之间进行切换。
但是,如果你用的是Jupyter,就完全不用这么麻烦了,你可以直接在命令之前放一个“!”,就能执行shell命令,完全不用切换来切换去,就能在IPython里执行任何命令行。
1 In [1]: !ls
2 example.jpeg list tmp
3 In [2]: !pwd
4 /home/Parul/Desktop/Hello World Folder'
5 In [3]: !echo "Hello World"
6 Hello World
7
2
3
4
5
6
7
我们甚至可以将值传递给shell,像下面这样:
1 In [4]: files= !ls
2 In [5]: print(files)
3 ['example.jpeg', 'list', 'tmp']
4 In [6]: directory = !pwd
5 In [7]: print(directory)
6 ['/Users/Parul/Desktop/Hello World Folder']
7 In [8]: type(directory)
8 IPython.utils.text.SList
2
3
4
5
6
7
8
注意,返回结果的数据类型不是列表。
# 7.matplotlib
# 头文件
import matplotlib.pyplot as plt
# 设置画图大小
plt.figure(figsize=(14,9))
# 画一个子图, height 为多少行,width为多少列, cnt为行主式编号(从1开始
ax = plt.subplot(height, width, cnt)
# x,y表示横纵数据(长度要一致),c表示颜色
#可选参数: marker='o' #表示圆圈,'*' => 星星
# label='y1-data' #标签
ax.plot(x, y, c = 'blue')
# 子图的标题,默认显示在正上方
ax.set_title(_title)
# 子图y轴的单位
ax.set_ylabel(_y_label)
# 保存图片
plt.savefig(f"{_path}/pic-{cnt}.png")
# 在图片中给出示例
plt.legend()
# 显示
plt.show()
# 当在一个进程中多次使用plt,可能导致内存不足
plt.close('all') #避免内存泄漏
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
# 8.numpy
https://www.cnblogs.com/yuxuanlian/p/numpy.html
# 1.np.array和list转换
# list to np.array
a = []
np_a = np.array(a)
# np.arrry to list
a = np_a.tolist()
2
3
4
5
# 2.np的除法
# 除法的意义是对应位置除
# [3, 4, 5] / [2, 2, 2] = [1.5, 2, 2.5]
rst = np.array([3, 4, 5]) / np.array([2, 2, 2])
2
3
# 9.clipboard
场景需求:需要把一个excel表里的某行元素快速的转置
import clipboard
text = clipboard.paste() # text will have the content of clipboard
clipboard.copy('\t'.join(text.split())) # now the clipboard content will be string "abc"
2
3
4
# 10. hexdump
文档: https://pypi.org/project/hexdump/
hexdump('\x00'*16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2
hexdump(data)
data需要是bytes
# 11. Serial
直接上样例
import serial
with serial.Serial('COM3', 115200, timeout=1) as ser:
x = ser.read() # read one byte
s = ser.read(10) # read up to ten bytes (timeout)
line = ser.readline() # read a '\n' terminated line
ser.write(b'hello') # write a string
ser.close() # close port
2
3
4
5
6
7
8
9
10
动态接受串口数据的大致逻辑
# 需求大致如下:
# 协议开头会发送 "AA", 之后每256个字节为一个page,每次处理256的字节,并且需要提供传输速度
# 总数为COUNT个page
with serial.Serial("COM3", 115200) as ser:
header = 0
buff_data = b''
cnt = 0
while header < 2:
ch = ser.read()
assert ch == b"A"
while True and cnt < COUNT:
lt = time.pref_counter()
while len(buff_data) < 256 and cnt < COUNT:
buff_data += ser.read(8192)
spd = len(buff_data) / (max(1e-9, time.pref_count() - lt))
while len(buff_data) >= 256 and cnt < COUNT:
page_data, buff_data = buff_data[:256], buff_data[256:]
run(page_data)
print(f"Completed {cnt} page {spd/1024:.2f}KB/S")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 12.multiprocessing
再用matplotlib画图时候,多线程处理同时处理多个文件时,发现用多线程会用资源冲突的情况
用多进程就会避免这种情况。大概逻辑如下
import multiprocessing
def fun(x):
print(f'{x} your function...')
if __name__ == '__main__':
processes = []
for i in S:
precessed.append(multiprocessing.Process(target=fun, arg=(i)))
for pro in processes:
pro.start()
for pro in processes:
pro.join()
2
3
4
5
6
7
8
9
10
11
12
# 13. xlwings
python 表格轮子比较
https://zhuanlan.zhihu.com/p/23998083
https://docs.xlwings.org/zh_CN/latest/installation.html
# 安装
pip install xlwings
# 应用如下,创建多个工作表,分别在对应位置插入数据
app = xw.App()
wb = app.books.add()
for sub_type in _type.keys():
sht = wb.sheets.add(sub_type)
sht.range('A2:H2').value = ['Bit', 'Size', 'MS', 'DS', 'ALL', 'MS', 'DS', 'ALL', '']
sht.range('A3:H3').value = stat_data_final[_type[sub_type]]
sht.autofit()
wb.save(f"{result_path}/{now_time_}__result_avg_final.xlsx")
print(f"Total make table time is {(time.time() - start_time):.3f}s.")
2
3
4
5
6
7
8
9
10
11
12
13
# 14. struct
将字节串解读为打包的二进制数据
https://docs.python.org/zh-cn/3.8/library/struct.html
应用场景:当python与其他语言交互的时候,难免会遇到二进制数据的问题,不然不好处理对齐问题
# 存入 path 路径下的 a.txt 文件,4字节小端对齐
with open(path, 'w') as fi:
fi.write(struct.pack('<ii', 1, 2))
2
3