? day 17-20 -----------------------
?对象序列化和反序列化
# 热身练习:将100以内的素数输出到文件中 # 素数判断函数 def is_prime(num: int) -> bool: ''' 判断一个正整数是否是质数 :param num: 正整数 :return: 质数返回True,否则返回False ''' for i in range(2, int(num ** 0.5) 1): # 需取到num**0.5 if num % i == 0: return False return True with open('prime.txt', 'w', encoding='utf-8') as file: for n in range(2, 100): if is_prime(n): # 方法一: print(n, file=file) # 将结果打印到文件中,而不是控制台 # 方法二: file.write(str(n)) file.write('\n') # 换行符 # 方法三: file.write(f'{
n}\n') # 格式化字符串
1. 将字典和列表写入文件
对象序列化(serialization)和反序列化(deserialization)
-
序列化:将对象(字典、列表等)变成字符串(str)或者字节串(bytes)
-
反序列化:从字节串或字符串中恢复一个对象(字典、列表等)
ython的标准库有**json(字符串) / pickle(字节串)**模块,可以支持我们做序列化和反序列化操作
JSON —> JavaScript Object Notation —> JavaScript语言创建对象的字面量语法 (字面量:常数量)
例如:
let person = {
name: "骆骆",
age: 41,
sex: True
}
这种数据格式也非常适合在两个系统(尤其是异构的系统)传输数据(因为它是纯文本),所以今天当我们说到JSON,更多的时候是把它当成一种数据交换格式。
Python中的字典跟JSON格式非常的像,所以我们可以通过将字典转成JSON格式的字符串,就可以写入文件中实现持久化。
文件保存数据的方式:
-
二进制文件,字节串
-
文本文件,字符串
json序列化,其他编程语言能读出来
pickle序列化,是python的私有化语言,其他编程语言不能读出来
2 序列化和反序列化
2.1 json模块
Python3 中可以使用 json 模块来对 JSON(文本文件) 数据进行编解码,它包含了两个函数:
- ( - 把一个对象(字典、列表等)变成字符串(str)或者字节串(bytes))
- 对数据进行编码。
- 对数据进行编码。
2)( - 从字节串或字符串中还原出一个对象(字典、列表等))
-
对数据进行解码。
-
**json.load(fp=文件对象)😗*对数据进行解码。
2.1.1 序列化(字典和列表写入到文件 - dumps)
将字典和列表写入到文件中
import json
person = {
'name': '骆骆',
'age': 41,
'sex': True,
'friends': ['赵云', '马超', '辛弃疾'],
'car': {
'brand': 'QQ',
'max_speed': 120
}
}
with open('person.txt', 'w') as file:
# 序列化
# 方法一:(分解写法)
# content = json.dumps(person)
# file.write(content)
# 方法一:(合并写法)
# print(json.dumps(person), file=file)
# 方法二:
json.dump(person, fp=file)
2.1.2 反序列化(字符串还原成(字典)对象)
读取文件中的JSON格式数据还原成字典对象
反序列化:将字符串还原成(字典)对象
import json
with open('person.txt') as file:
# 反序列化:将字符串还原成(字典)对象
# content = file.read()
# obj = json.loads(content)
# 从文件中读取JSON字符串还原成字典对象
obj = json.load(fp=file)
print(obj)
print(type(obj))
2.2 pickle模块
Python3 中可以使用 pickle 模块来对 二进制文件 数据进行编解码,它包含了两个函数:
- 对数据进行编码。
- :对数据进行编码。
- 对数据进行解码。
2.3.1 序列化
将字典和列表写入到文件中
import pickle
person = {
'name': '骆骆',
'age': 41,
'sex': True,
'friends': ['赵云', '马超', '辛弃疾'],
'car': {
'brand': 'QQ',
'max_speed': 120
}
}
with open('person.dat', 'wb') as file:
# 序列化
# print(json.dumps(person), file=file)
# content = json.dumps(person)
# file.write(content)
pickle.dump(person, file=file)
2.3.2 反序列化
读取文件中的Pickle格式数据还原成字典对象
反序列化:将字节串(二进制数据)还原成(字典)对象
import pickle
with open('person.dat', 'rb') as file:
# 反序列化:将字节串(二进制数据)还原成(字典)对象
obj = pickle.load(file)
print(obj)
print(type(obj))
# 结果:
# {'name': '张三', 'age': 18, 'gender': True, 'friends': ['小花', '小明'], 'car': {'brand': 'QQ', 'max_speed': 120}}
# class 'dict'>
❤ 联网获取数据(通过API接口获取数据)
URL —> 网址 —> 统一资源定位符 —> 能够唯一标识一个(网络)资源的符号
URL —> Universal Resource Locator —>唯一标识一个(网络)资源
例如:百度首页
https://www.baidu.com/ 简写版
https://www.baidu.com:443/index.html 完整版
https://14.215.177.38:443/index.html IP地址版
https://www.baidu.com:443/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png
例如:豆瓣网
https://movie.douban.com:443/top250
https://movie.douban.com/top250?start=25&filter= ?后的不属于URL的内容,是请求参数
URI —> 统一资源标识符 —> URL + URN
使用三方库 requests 可以非常方便的实现通过URL访问网络资源的操作 可以使用Python的包管理工具 pip 来安装和管理三方库以及三方工具
修改 pip 下载源为国内的镜像网站(推荐使用豆瓣网的镜像) pip config set global.index-url https://pypi.doubanio.com/simple
检查有没有pip包:terminal(py文件下方位置) - 输入:pip --version
查找三方库:pip search requests 安装三方库:pip install requests 卸载三方库:pip uninstall requests 更新三方库:pip install -U requests
协议 —> 规范和标准 —> 网络协议 —> 通过网络进行通信的双方要遵守的规范和标准 HTTP —> 超文本传输协议 —> 请求响应式协议
HTTP -> 超文本传输协议 HTTP(S) -> 超文本传输协议(安全版本)
3.1 导入第三方库 requests
首先,安装第三方库requests
,使用前需先导入.
import requests
3.1 requests 模块
- 通过指定的URL向Web服务器发起一个请求,该函数会返回一个相应对象
网页上获取数据:例如:从聚合数据平台获取天气数据:聚合数据 —> 天气预报(查看) —> 申请数据(得到key) —> 测试 —> 填入请求参数 -> 发送请求
3.2 通过python联网获取数据
通过python联网获取数据:例如:从聚合数据平台获取天气数据:聚合数据 —> 天气预报 —> 申请数据,获取key
—> 查看天气预报中的API文档
,获取接口地址
(http://apis.juhe.cn/simpleWeather/query),获取请求参数
# 从聚合数据平台获取天气数据
# 聚合数据 ---> 天气预报 ---> 申请数据,获取`key`---> 查看天气预报中的`API文档`,获取`接口地址`(http://apis.juhe.cn/simpleWeather/query),获取`请求参数`
import json
import requests
# get函数会通过你指定的URL向Web服务器发起一个请求,该函数会返回一个响应对象
resp = requests.get(
url='http://apis.juhe.cn/simpleWeather/query',
params={
'city': '上海',
'key': 'e73ebce8dc3cb2f35510f4462f08430c'
}
)
# 获取服务器响应的内容并将其反序列化成一个字典对象
weather_dict = json.loads(resp.text)
print(weather_dict['result']['realtime'])
# futures = weather_dict['result']['future']
# for future in futures:
# print(future)
# 聚合数据 - 手机归属地
import json
import requests
url = 'http://apis.juhe.cn/mobile/get'
key = 'a85eb75a4850c5502be6ff253e70b5f2'
phone = '15882460234'
resp_phone_belong = requests.get(
url = url,
params={
'key':key,
'phone':phone
}
)
print(resp_phone_belong.text) # .text - 获取网页内容,得到网页内容的字符串
phone_belong_dict = json.loads(resp_phone_belong.text) # .loads - 反序列化,将字符串转换为字典
print(phone_belong_dict)
# 天行数据 - 头条新闻获取
# 每页获取10条新闻
for page in range(1,6):
resp_news = requests.get(
url = 'http://api.tianapi.com/topnews/index',
params={
'key':'e8c5524dd2a365f20908ced735f8e480',
'page':page,
'num':10
}
)
result = resp_news.json() # 将resp_news转换为字典【待查证】
for news_dict in result['newslist']:
print(news_dict['title']) # 新闻标题
print(news_dict['url']) # 新闻链接
print(news_dict['source']) # 新闻来源
print('-'*30)
3.3 通过响应对象获取服务器返回的内容
-
- 通过响应对象获取服务器返回的文本内容
-
- 通过响应对象获取服务器返回的二进制数据
# 通过响应对象获取服务器返回的内容
import requests
resp = requests.get('https://www.sohu.com/')
# 通过响应对象获取服务器返回的文本内容
print(resp.text)
resp = requests.get('http://29e5534ea20a8.cdn.sohucs.com/c_cut,x_47,y_0,w_588,h_392,c_zoom,h_103/os/news/d5d461792f7944f11e9ed9a2bd2ff7a5.jpg')
with open('test.jpg', 'wb') as file:
# 通过响应对象获取服务器返回的二进制数据
file.write(resp.content)
from datetime import datetime
import openpyxl
import requests
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.append(('标题', '链接', '来源'))
for page in range(1, 6):
resp = requests.get(
url='http://api.tianapi.com/topnews/index',
params={
'key': 'e8c5524dd2a365f20908ced735f8e480',
'page': page,
'num': 20
}
)
result = resp.json()
for news_dict in result['newslist']:
title, url, source = news_dict['title'], news_dict['url'], news_dict['source']
sheet.append((title, url, source))
curr = datetime.now()
workbook.save(f'头条新闻数据_{
curr.year}{
curr.month:0>2d}{
curr.day:0>2d}.xlsx')
❤ 用python操作Excel文件
4.1 导入第三方库 openpyxl
工作簿(workbook):一个Excel文件叫一个工作簿
工作表(sheet) :工作簿中的一个表格叫做一个工作表
单元格(cell):Excel文件表中表格的行列交汇点叫单元格
python操作Excel文件需借助第三方库
首先,安装第三方库openpyxl
,使用前需先导入
import openpyxl
4.2 创建工作簿
创建一个Excel工作簿
workbook = openpyxl.Workbook()
创建工作表
workbook.create_sheet('hello')
获取默认的工作表
sheet = workbook.active
4.3 将数据写入Excel文件
-
注意:想要把多个数据写在同一行,并分别填入多个单元格,就需要将数据以序列的方式传入
-
注意:工作表中的行索引和列索引都是从1开始的
sheet.append(('姓名', '语文', '数学', '英语'))
# sheet.append(['姓名', '语文', '数学', '英语'])
sheet.append(('张三', 50, 60, 70))
sheet.append(('李四', 53, 66, 72))
sheet.append(('王五', 51, 67, 74))
sheet.cell(5, 1, '小明') # 在5行4列单元格写入'小明'
4.4 保存工作簿
workbook.save('学生成绩表.xlsx')
练习:
# 练习:从天行数据获取头条新闻,并将数据保存至excel
news = openpyxl.Workbook()
# news.create_sheet('news')
sheet = news.active
# sheet.append(('title'))
for page in range(1, 6):
resp_news = requests.get(
url='http://api.tianapi.com/topnews/index',
params={
'key': 'e8c5524dd2a365f20908ced735f8e480',
'page': page,
'num': 10
}
)
result = resp_news.json() # 将resp_news转换为字典
for news_dict in result['newslist']:
title,url,source = news_dict['title'], news_dict['url'], news_dict['source']
sheet.append((title, url, source))
# sheet.append((news_dict['url']))
# sheet.append((news_dict['source']))
# print(news_dict['title']) # 新闻标题
# print(news_dict['url']) # 新闻链接
# print(news_dict['source']) # 新闻来源
# print('-'*30)
curr = datetime.now() # 获取当前的结构体时间
news.save(f'新闻_{
curr.year}{
curr.month:0>2d}{
curr.day:0>2d}.xlsx') # 文件名中加日期
4.5 读取Excel文件
如何用Excel打开乱码文件:现将文件另存为UTF-8 with BOM utf8bom文件,再用Excel打开
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeLAOAQy-1634975911748)(C:\Users\32873\AppData\Roaming\Typora\typora-user-images\image-20211012091006237.png)]
4.5.1 加载Excel文件
#读取excel文件
import openpyxl
# 加载Excel文件 ---> Workbook
workbook = openpyxl.load_workbook('resources/口罩销售数据.xlsx')
# 获取所有工作表的名字
print(workbook.sheetnames)
# 获得第一个工作表 ---> Worksheet
sheet = workbook.worksheets[0]
# 获取单元格的数据
print(sheet.cell(3, 4).value)
print(sheet['D3'].value)
# 单元格的范围
print(sheet.dimensions)
# 获取表格的行数和列数
print(sheet.max_row, sheet.max_column)
# 循环遍历所有的数据
# for row in range(1, sheet.max_row + 1):
# for col in range(1, sheet.max_column):
# print(sheet.cell(row, col).value, end='\t')
# print()
for row in range(2, sheet.max_row + 1):
for col in 'ABCDEF':
print(sheet[f'{
col}{
row}'].value, end='\t')
print()
例如:
在当前⽂文件夹下有⼀一个名为“阿⾥里里巴巴2020年年股票数据.xlsx”的Excel⽂文件,如果想读取并显示该⽂文件的内容, 可以通过如下所示的代码来完成。
import datetime
import openpyxl
# 加载⼀一个⼯工作簿 ---> Workbook
wb = openpyxl.load_workbook('阿⾥里里巴巴2020年年股票数据.xlsx')
# 获取⼯工作表的名字
print(wb.sheetnames)
# 获取⼯工作表 ---> Worksheet
sheet = wb.worksheets[0]
# 获得单元格的范围
print(sheet.dimensions)
# 获得⾏行行数和列列数
print(sheet.max_row, sheet.max_column)
# 获取指定单元格的值
print(sheet.cell(3, 3).value) #通过cell方法
print(sheet['C3'].value) # 通过单元格
print(sheet['G255'].value) # 通过单元格
# 获取多个单元格(嵌套元组) - 返回嵌套的元组
print(sheet['A2:C5']) # 通过切片
# print(sheet['A2':'C5'])
# 读取所有单元格的数据
for row_ch in range(2, sheet.max_row + 1):
for col_ch in 'ABCDEFG':
value = sheet[f'{
col_ch}{
row_ch}'].value
if type(value) == datetime.datetime:
print(value.strftime('%Y年年%m⽉月%d⽇日'), end='\t') # \t:表示空四个字符,或一个缩进/制表符/Tab键
elif type(value) == int:
print(f'{
value:<10d}', end='\t')
# X < Nd - 将数据转换为长度为N的字符串,不够在后面用X(默认为空格)对应的字符来填充
elif type(value) == float:
print(f'{
value:.4f}', end='\t')
# .Nf - 保留N位小数
else:
print(value, end='\t')
print()
❤ 用python操作CSV文件
CSV(Comma Separated Values)全称是⼀一种简单、通⽤用的⽂文件格式,被⼴广泛的应⽤用于应⽤用程序 (数据库、电⼦子表格等)数据的导⼊入和导出以及异构系统之间的数据交换。因为CSV是纯⽂文本⽂文件,不不管是什什么操 作系统和编程语⾔言都是可以处理理纯⽂文本的,⽽而且很多编程语⾔言中都提供了了对读写CSV⽂文件的⽀支持,因此CSV格式在 数据处理理和数据科学中被⼴广泛应⽤用。
使用方法参见 ‘第23课:⽤用Python读写CSV⽂文件.pdf’
1. 读取CSV文件
常用的字符编码为’utf - 8’
若文件存为了UTF-8 with BOM utf8bom文件,则相应的字符编码为’utf-8-sig’
1utf - 8 - sig 带签名的UFT-8 —> 有字节序标记
with open('./resources/2018年北京积分落户数据.csv', 'r', encoding='utf-8-sig') as file:
# utf - 8 - sig 带签名的UFT-8 ---> 有字节序标记
content = file.readline() # 读取一行内容
# file.readlines() # 可一次性读完文件所有内容,但不推荐该做法(因为文件很大时,内存消耗太大)
while content:
print(content, end='')
content = file.readline()
# 注意:如果读取UTF-8 with BOM utf8bom文件时指定encoding='utf-8',读出结果结果中可能会多出一点内容,例如:
with open('./resurces/2018年北京积分落户数据.csv', 'r', encoding='utf-8') as file:
# 结果:
# ['\ufeffid', 'name', 'birthday', 'company', 'score']
# 其中的feff是字节序标记,因为该文件为UTF-8 with BOM utf8bom文件,即为带签名的UFT-8的文件,encoding='utf-8-sig'
with open('./resources/2018年北京积分落户数据.csv', 'r', encoding='utf-8-sig') as file:
reader = csv.reader(file, delimiter='#') #
# csv.reader()的参数还有:
# delimiter(默认是逗号)
# 该文件为逗号分隔的文件,若为其他符号作为分隔符的文件,则需要用参数delimeter(默认是逗号)进行指定(需与原文件的分隔符相同),否则会将整个一行作为同一个字符串读出(即一行只有一个元素)
# quotechar='|' - 去掉包围符|
# 如果值带有包围符(双引号,或|),但不想读出|,就需要用参数quotechar='|'来去除包围
for line in reader:
print(line)
2. 将数据写入CSV文件
# newline='' - 这样追加后就不会出现空行 with open('./resources/2018年北京积分落户数据.csv', 'a', encoding='utf-8-sig', newline='') as file: writer = csv.writer(file 标签:
edc17主继电器1cut继电器nf系列abb中间继电器rk211186中间继电器ps2继电器cr系列中间继电器