struct模块

最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结。

了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int,char,bool等等),方便对某一结构对象进行处理。而在网络通信当中,大多传递的数据是以二进制流(binary data)存在的。当传递字符串时,不必担心太多的问题,而当传递诸如int、char之类的基本数据的时候,就需要有一种机制将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据。python中的struct模块就提供了这样的机制,该模块的主要作用就是对python基本类型值与用python字符串格式表示的C struct类型间的转化(This module performs conversions between Python values and C structs represented as Python strings.)。stuct模块提供了很简单的几个函数,下面写几个例子。

1.基本的pack和unpack

struct提供用format specifier方式对数据进行打包和解包(Packing and Unpacking)。例如:

import struct
import binascii # 字符串转换模块 # 1.struct 基础应用
values = (1, 'abc'.encode("utf8"), 2.7) # python3 需要转化成bytes类型
s = struct.Struct('I3sf') # 定义format 格式 格式参考help(struct) #??大端存储小端存储???何以?
packed_data = s.pack(*values) # 这个地方要是字符串必须用bytes类型
print(packed_data) # 打印pack的bytes类型
print(len(packed_data)) # 长度为12字节
print(binascii.hexlify(packed_data)) # 打包后的十六位值的表示
unpacked_data = s.unpack(packed_data)
print(unpacked_data)
# 输出结果
# b'\x01\x00\x00\x00abc\x00\xcd\xcc,@'
# 12
# b'0100000061626300cdcc2c40'
# (1, b'abc', 2.700000047683716) 代码中,首先定义了一个元组数据,包含int、string、float三种数据类型,然后定义了struct对象,
并制定了format‘I3sf’,I 表示int,3s表示三个字符长度的字符串,f 表示 float。
最后通过struct的pack和unpack进行打包和解包。
通过输出结果可以发现,value被pack之后,转化为了一段二进制字节串,而unpack可以把该字节串再转换回一个元组,
但是值得注意的是对于float的精度发生了改变,这是由一些比如操作系统等客观因素所决定的。打包之后的数据所占用的字节数与C语言中的struct十分相似。
定义format可以参照官方

api提供的对照表:

2.字节顺序

另一方面,打包的后的字节顺序默认上是由操作系统的决定的,当然struct模块也提供了自定义字节顺序的功能,可以指定大端存储、小端存储等特定的字节顺序,对于底层通信的字节顺序是十分重要的,不同的字节顺序和存储方式也会导致字节大小的不同。在format字符串前面加上特定的符号即可以表示不同的字节顺序存储方式,例如采用小端存储 s = struct.Struct(‘<I3sf’)就可以了。官方api library 也提供了相应的对照列表:

3.利用buffer,使用pack_into和unpack_from方法

使用二进制打包数据的场景大部分都是对性能要求比较高的使用环境。而在上面提到的pack方法都是对输入数据进行操作后重新创建了一个内存空间用于返回,也就是说我们每次pack都会在内存中分配出相应的内存资源,这有时是一种很大的性能浪费。struct模块还提供了pack_into() 和 unpack_from()的方法用来解决这样的问题,也就是对一个已经提前分配好的buffer进行字节的填充,而不会每次都产生一个新对象对字节进行存储。

	import ctypes

	# 2.
value1 = (2, b"asxc", 5.0)
value2 = (b"tteedd", 5.1)
s1 = struct.Struct("I4sf")
print(s1.size)
s2 = struct.Struct("6sf")
print(s2.size)
prebuffer = ctypes.create_string_buffer(s1.size + s2.size) # 初步理解创建一个buffer的字符数字内存地址
print(prebuffer)
s1.pack_into(prebuffer, 0, *value1)
s2.pack_into(prebuffer, s1.size, *value2) # 给这个buffer后面接数字位置 unpack的时候需要用位置 加struct的格式unpack
print(prebuffer)
print(s1.unpack_from(prebuffer, 0))
print(s2.unpack_from(prebuffer, s1.size))
# 输出结果
# 12
# 12
# <ctypes.c_char_Array_24 object at 0x000000000055ECC8>
# <ctypes.c_char_Array_24 object at 0x000000000055ECC8>
# (2, b'asxc', 5.0)
# (b'tteedd', 5.099999904632568)

csv模块

csv文件格式是一种通用的电子表格和数据库导入导出格式。最近我调用RPC处理服务器数据时,经常需要将数据做个存档便使用了这一方便的格式。

1.第一种方法使用reader函数,接收一个可迭代的对象(比如csv文件),能返回一个生成器,就可以从其中解析出csv的内容:比如下面的代码可以读取csv的全部内容,以行为单位:
 with open(r"E:\学习之路第一章\路边拾遗技能请看\zjj.csv", 'r') as f:
data = csv.reader(f, ) # CSV 模块打开对象,得到一个文件迭代对象,注意迭代对象取值完成之后在取值为空了
for row in data:
print(row)
# 输出结果
# ['id', 'name', 'age', 'addr']
# ['1', '张三', '23', '北京']
# ['2', '李四', '22', '上海']
# ['3', '小黑', '18', '深圳']
# ['4', '小红', '33', '杭州']
# ['1', '赵五', '23', '青岛'] with open(r"E:\学习之路第一章\路边拾遗技能请看\zjj.csv", 'r') as f:
data = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE) # CSV 模块打开对象,得到一个文件迭代对象,
# 指定读取时的文件格式什么格式分列表的一个值
for row in data:
print(row)
# 输出结果
# ['id,name,age,addr']
# ['1,张三,23,北京']
# ['2,李四,22,上海']
# ['3,小黑,18,深圳']
# ['4,小红,33,杭州']
# ['1,赵五,23,青岛']
if row[0] == "id": # 判断如果第一行第0个等于"id" 则读取第一行 序列为3的字符
print(row[3]) # 打印文件的每一行组成一个列表
rows = [row for row in data] # 生成一个列表每行是一个子列表
print(rows)
# 读取指定列的数据
cloumn = [row[0] for row in data] # row[0]表示第几列数据
print(cloumn) # ['id', '1', '2', '3', '4']

2.文件写入

读文件时,我们把csv文件读入列表中,写文件时会把列表中的元素写入到csv文件中。

import csv
row = ["1", "赵五", "23", "青岛"] # 生成一行需要插入的数据,可以从数据库读取组成元祖
with open(r"E:\学习之路第一章\路边拾遗技能请看\zjj.csv", 'a', newline="") as f:
csv_writer = csv.writer(f) # 生成一个writer的对象 csv下面的生成writer的方法
csv_writer.writerow(row) # 用生成的writer这个对象 执行writerow方法写入文件

注意:如果以rb的模式打开读或者写这样操作文件比较方便。

表格处理写入模块xlwt

表格读取模块在常用模块内

import xlrd
import xlwt # xlwt xls文件写入模块
# xlwt基本用法
write_book = xlwt.Workbook() # 生成一个write_book对象
sheet_w = write_book.add_sheet("demo2") # 给生成的write_book 对象添加一个sheet页
book = xlrd.open_workbook("b.xls") # 打开一个xls格式的文件,获得一个对象
sheet = book.sheet_by_index(0) # 获得打开对象的一个sheet页0
print(sheet)
print(sheet.row_values(0)) # 获得对应sheet页的行的值是一个list
for i, val in enumerate(sheet.row_values(0)):
sheet_w.write(0, i, val) # 0 是代表第几行 这个i 是用来定位写在表格一行的那个位置,val 写入的值
write_book.save("c.xls") # 2.设置样式写入,字体样式导尿管其他设置高级设置 workbook = xlwt.Workbook(encoding='ascii')
worksheet = workbook.add_sheet('My Worksheet')
style = xlwt.XFStyle() # 初始化样式
font = xlwt.Font() # 为样式创建字体
font.name = 'Times New Roman'
font.bold = True # 黑体
font.underline = True # 下划线
font.italic = True # 斜体字
style.font = font # 设定样式
worksheet.write(0, 0, 'Unformatted value') # 不带样式的写入 worksheet.write(1, 0, 'Formatted value', style) # 带样式的写入 workbook.save('formatting.xls') # 保存文件 # 转自 https://blog.csdn.net/Tulaimes/article/details/71172778

发送邮件SMTP模块

下面是邮件发送带附件的形式:

	# _*_ coding:utf-8 _*_
# __author__Zj__
from email.header import Header
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText sender = '529505291@qq.com'
user = '529505291@qq.com'
password = "tivknkxxxxxxxxx"
receivers = ['529505291@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 # 创建一个带附件的实例
message = MIMEMultipart()
message['From'] = Header("发件人名称需要配置", 'utf-8') # 发件人
message['To'] = Header("收件人名称", 'utf-8') # 收件人
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8') # 邮件正文内容
message.attach(MIMEText('邮件正文需要书写内容的', 'plain', 'utf-8')) # 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open(r'E:\学习之路第一章\路边拾遗技能请看\常规奇思妙想练习\庄杰周报.xls', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.xls"' # 命名 附件的文件格式 与文件名字
message.attach(att1) # 构造附件2,传送当前目录下的 runoob.txt 文件
att2 = MIMEText(open(r'E:\学习之路第一章\路边拾遗技能请看\WokerPlace\DIFF_ORDER_20180420_ALIPAY', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="DIFF_ORDER_20180420_ALIPAY.txt"'
message.attach(att2)
roadservice = "smtp.qq.com" # 使用QQ邮箱发送
try:
smtpObj = smtplib.SMTP_SSL(roadservice, 465)
smtpObj.login(user, password) # 开通SMTP的 用户名字跟密码
smtpObj.sendmail(sender, receivers, message.as_string()) except smtplib.SMTPException:
pass

RSA加密

"""简单的加密解密方法"""

import rsa
def rsaEncrypto(str):
# 定义加密的算法模式
Pub_Key, Pri_Key = rsa.newkeys(256)
# 把内容定义为编码格式UTF8
content = str.encode("utf8")
# 对content 用公钥加密返回加密文本
crypto = rsa.encrypt(content, Pub_Key)
# 返回 加密的字符串 与私钥
return (crypto, Pri_Key) def rsaDecrypto(crystr, pri_key):
content = rsa.decrypt(crystr, pri_key)
return content.decode("utf8")

路边拾遗之其他模块(struct/csv/xlwt/smtp)的更多相关文章

  1. Python操作Excel——win32com模块和xlrd+xlwt+xlutils组合

    今天,接到一个任务,要生成大约两百个excel文件,从2006年到2013年,每个月两个文件,这些文件中除了几个关于日期的单元格不同外,其他数据都相同,所以就想到可以用python写一个小脚本,自动生 ...

  2. python3csv与xlsx文件操作模块(csv、xlsxwriter)

    一.csv模块实现csv文件操作 1.CSV介绍 CSV,全称为Comma-Separated Values,它以逗号分隔值,其文件以纯文本形式存储表格数据,该文件是一个字符序列,可以由任意数目的记录 ...

  3. python day 8: re模块补充,导入模块,hashlib模块,字符串格式化,模块知识拾遗,requests模块初识

    目录 python day 8 1. re模块补充 2. import模块导入 3. os模块 4. hashlib模块 5. 字符串格式:百分号法与format方法 6. 模块知识拾遗 7. req ...

  4. configparser模块,subprocess 模块,xlrd,xlwt ,xml 模块,面向对象

    1. configparser模块 2.subprocess 模块 3.xlrd,xlwt 4.xml 模块 5.面向对象 面向对象是什么? 是一种编程思想,指导你如何更好的编写代码 关注点在对象 具 ...

  5. python3使用csv模块读写csv文件

    python3使用csv模块读写csv文件 读取csv文件: import csv #打开文件,用with打开可以不用去特意关闭file了,python3不支持file()打开文件,只能用open() ...

  6. python 模块:csv

    转自:http://www.cnblogs.com/sislcb/archive/2008/12/15/1355481.html (感谢整理) 举几个例子来介绍一下,Python 的 CSV模块的使用 ...

  7. python 网络编程--socket模块/struct模块

    socket模块: 客户端:CS架构,  client -> server 浏览器:BS架构,  browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...

  8. 四十四 常用内建模块 struct

    准确地讲,Python没有专门处理字节的数据类型.但由于str既是字符串,又可以表示字节,所以,字节数组=str.而在C语言中,我们可以很方便地用struct.union来处理字节,以及字节和int, ...

  9. python读写Excel文件_xlrd模块读取,xlwt模块写入

    一.安装xlrd模块和xlwt模块(服务器) 1. 下载xlrd模块和xlwt模块 到python官网http://pypi.python.org/pypi/xlrd下载模块.下载的文件例如:xlrd ...

随机推荐

  1. 删除 mac 垃圾桶内清除不掉的文件

    命令行 内 $ sudo rm -rf ~/.Trash/

  2. Redis 安装,配置,简介,数据类型(一)

      Redis 安装 Window 下安装 下载地址:https://github.com/MSOpenTech/redis/releases. Redis 支持 32 位和 64 位.这个需要根据你 ...

  3. 20165210 2017-2018-2《Java程序设计》课程总结

    20165210 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总: 预备作业一: 20165210 我期望的师生关系 预备作业二:20165210 学习基础和C语言基 ...

  4. 2017.11.6对比Gerber差异+确认元器件方向,封装

    1比对新旧版本的gerber差异      导入两个版本.其中主要的是bot(底层),Smt(元器件),sst(丝印层),top(顶层) 底层和顶层可以看出走线layout的差别,这点很重要,上次客户 ...

  5. 【python】利用h5py存储数据

    两类容器:group & dataset group类似文件夹,字典. dataset是数据集,类似数组 支持更多的对外透明的存储特征,数据压缩,误差检测,分块传输 group下面可以是gro ...

  6. [转载]Python注册表信息丢失的解决方案

    今天安装Python的模块时,安装失败,提示信息:Python version 2.7 required, which was not found in the registry. 原因在于Pytho ...

  7. BAT级别对照表

  8. Photoshop脚本指南——Hello World

    作为一个程序猿,每一个东西的学习都是从Hello World开始的,从今天开始,让我们一起进入Photoshop脚本的世界,并以Hello World开始我们的旅程. 1.简介 Photoshop支持 ...

  9. Matisse,来自知乎的PhotoPicker

    简介 Matisse,是一款由知乎开源的媒体选择器. 在Activity和Fragment中使用 支持JPEG,PNG,GIF的图片选择和MPEG,MP4格式的视频选择.不能同时选择图片和视频 两种主 ...

  10. Azure Sql Database为某个数据库创建单独的访问账户

    由于SQL Management Studio对Azure SQL Database支持不完美,不能使用图形界面,因此配置数据库就会有不同的麻烦,下面是本人配置访问账户的一些经验: 1.以管理员登陆之 ...