Skip to content

Latest commit

 

History

History
247 lines (185 loc) · 5.07 KB

File metadata and controls

247 lines (185 loc) · 5.07 KB
Error in user YAML: (<unknown>): could not find expected ':' while scanning a simple key at line 3 column 1
---
- oeasy Python 0447
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
本教程同步发布在: 

     个人网站: `https://oeasy.org` 
     蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
     GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
     Gitee: `https://gitee.com/overmind1980/oeasypython` 
---

序列化

回忆

  • 上次我们研究数据序列化
    • 字符串
    • 字节型整数
    • 双精度浮点数
  • 依次写入
    • 然后可以进行数据类型转化
    • 并且进行运算
  • 可以对于序列化
    • 定点写入
    • 定点读取
  • 这并不难
  • 我们可以按照需求对文件进行读写操作么?

尝试使用命令行参数

  • 从游乐场跳转到操练场

图片描述

  • 带参数运行

图片描述

  • 实验结果明确

尝试序列化写入

import sys
import struct

f = open(sys.argv[1],"wt")
f.write(sys.argv[2])
f.write("\n")
f.close()
f = open(sys.argv[1],"ab")
hours = int(sys.argv[3])
b_hours = struct.pack("b",hours)
f.write(b_hours)
salary = float(sys.argv[4])
d_salary = struct.pack("d",salary)
f.write(d_salary)
f.close()
  • 给参数
python3 write.py oeasyd oeasy 4 11.1

查看结果

  • oeasyd结果

图片描述

  • %!xxd

图片描述

读出来

图片描述

  • 由于不知道name长度
    • 从结尾倒着回去
import sys
import struct
f = open(sys.argv[1],"rb")
b_name = f.readline()
s_name = b_name.decode()
s_name = s_name.replace("\n","")
f.close()
f = open(sys.argv[1],"rb")
f.seek(-9,2)
hours = f.read(1)
b_hours = struct.unpack("b",hours)[0]
f.seek(-8,2)
salary = f.read(8)
d_salary = struct.unpack("d",salary)[0]
f.close()
print(s_name,b_hours,d_salary)
  • 读出来是没问题的
    • 问题现在读了两次
  • 有可能只读一次
    • 然后切片(slice)么?

实验

图片描述

  • 现在得到的是一个字节序列

处理

  • 首先是不知道名字有多长
    • 如果我知道总长度
    • 然后减去后面的 9 个字节的数字位置
    • 然后再减去一个分隔符
    • 就可以知道名字的长度了

图片描述

  • 其实现在需要做的
    • 就是找到各个变量的首末位置
  • 只不过原来用的是f.seek
    • 现在应该用序列索引的方式

切片

  • 既然知道了名字字符串的长度
    • 然后就可以把名字先切出来
  • 用到的是一个切片操作
    • [0:5] 从第 0 个字节到第 5 个字节之前

图片描述

  • 切完了名字继续切数字
    • 名字之后有个\n

继续读

  • 计算位置
    • 名字的长度是 5
    • 加上回车是 6
    • 第 6 个字节就是工作时长的字节整型数字
    • 所以使用[6:7]
    • 截取这个字节

图片描述

  • 然后准备读取工资

再读

  • 第6个字节工作时长
  • 第7个字节到第14个字节
  • 总共八个字节
  • 正好对应这个8字节浮点数

图片描述

  • 读取出 double 型的 salary 数值
  • 然后进行输出

图片描述

  • 完成!✿

文件

import sys
import struct
f = open(sys.argv[1],"rb")
b = f.read()
length = len(b)
s_name = b[0: length-9].decode()
s_name = s_name.replace("\n","")
f.seek(-9,2)
hours = f.read(1)
b_hours = struct.unpack("b",hours)[0]
f.seek(-8,2)
salary = f.read(8)
d_salary = struct.unpack("d",salary)[0]
f.close()
print(s_name,b_hours,d_salary)
  • 既然能够一把读出来
  • 可以一把写进去么?

字节流写入

图片描述

  • 字节流整合
  • 确实可以串起来
  • 这样一把写入字节流就更合理了
  • 但是有个小问题
  • 字符串和数字部分之前没有分隔符
  • 还是得有个\n

图片描述

  • 这样就成功一次写入了
  • 而且是序列化地写入
  • 再去读出来

读出

图片描述

  • 首先定点读出数据
    • 确认写的位置
  • 如果是修改呢?
    • 每次都需要全读需全写么?
    • 能否只修改工作时间?

定点

  • 具体写入

图片描述

  • 可以看到\n之后的字节值
    • 被从0x05修改为0x03
  • 试验成功
  • 你可以把他落实为文件么?

总结

  • 这次研究了配合命令行参数的读写
    • 通过参数传递数据
    • python文件接收参数
    • 具体写某个文件
    • 写入某些数据
    • 然后再读取出来
    • 甚至可以定点修改
  • 可以从多个文件中读取么?
    • 每个文件中一个数字
    • 然后把他们都加起来?🤔
  • 下次再说 👋

  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。