最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python中struct模塊之字節(jié)型數(shù)據(jù)的處理方法

 更新時間:2019年08月27日 10:48:12   作者:丶點小非  
今天小編就為大家分享一篇python中struct模塊之字節(jié)型數(shù)據(jù)的處理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

簡介

這個模塊處理python中常見類型數(shù)據(jù)和Python bytes之間轉(zhuǎn)換。這可用于處理存儲在文件或網(wǎng)絡連接中的bytes數(shù)據(jù)以及其他來源。在python中沒有專門處理字節(jié)的數(shù)據(jù)類型,建立字節(jié)型數(shù)據(jù)也比較麻煩,我們知道的bytes()函數(shù)也只能對無符號整型做處理,并且數(shù)據(jù)如下(沒錯,數(shù)字為多少就有多少個\x00,我們要是用這種方式來存儲大量數(shù)據(jù),結(jié)果可想而知):

va = bytes(1) # va: '\x00'
vb = bytes(2) # vb: '\x00\x00'
vc = bytes(5) # vc: '\x00\x00\x00\x00\x00'

但在python中str類型中既可以用字符串表示也可以以字節(jié)方式表示,所以你定義一個字節(jié)型的字符串常量,python是能處理它的:

va = '\x26' # va: '&'

struct處理

字節(jié)順序

一個數(shù)據(jù)有多個字節(jié)表示的時候,字節(jié)的順序不同也就決定了值,在struct中有以下幾種字節(jié)順序:

字符 字節(jié)順序 尺寸 對齊方式
@ 本機 本機 本機
= 本機 標準
< 小端 標準
> 大端 標準
! 網(wǎng)絡 標準

對于字節(jié)順序,只有大端和小端兩種方式,只是比如你用@和=代表你用本機的字節(jié)順序,!代表你使用網(wǎng)絡的字節(jié)順序。你不指定字節(jié)順序則默認的是@。

本地字節(jié)順序是大端或小端,取決于主機系統(tǒng)。例如,Intel x86和AMD64(x86-64)是小端的; 摩托羅拉68000和PowerPC G5是大端; ARM和Intel Itanium具有可切換的字節(jié)序(雙字節(jié)序)。使用sys.byteorder來檢查你的系統(tǒng)的字節(jié)順序。

數(shù)據(jù)格式

struct支持的打包解包的數(shù)據(jù)格式如下,我們需要指定格式才能對應處理,其中對應尺寸已列出(以字節(jié)為單位):

字符 C類型 python類型 標準尺寸
x 填充字節(jié) 沒有意義的值
c char 長度為1的字節(jié) 1
b signed char 整型 1
B unsigned char 整型 1
? _Bool 布爾 1
h short 整型 2
H unsigned short 整型 2
i int 整型 4
I unsigned int 整型 4
l long 整型 4
L unsigned long 整型 4
q long long 整型 8
Q unsigned long long 整型 8
n ssize_t 整型
N size_t 整型
e 浮動 2
f float 浮動 4
d double 浮動 8
s char[] 字節(jié)
p char[] 字節(jié)
P void * 整型

打包

通過struct的pack(fmt, *args)來實現(xiàn)對各種數(shù)據(jù)的打包(轉(zhuǎn)換為對應字節(jié)數(shù)據(jù)),pack的需要傳遞的參數(shù)fmt就是數(shù)據(jù)的格式,包括了字節(jié)順序、數(shù)據(jù)類型;后面的*args參數(shù)是需要打包的數(shù)據(jù)。

vaa = struct.pack('>I', 1255) # vaa: '\x00\x00\x04\xe7' 1*4=1個字節(jié) vab = struct.pack('>II', 1255, 23) # vab: '\x00\x00\x04\xe7\x00\x00\x00\x17' 2*4=8個字節(jié) vac = struct.pack('>2I?', 1255, 23, True) # vac: '\x00\x00\x04\xe7\x00\x00\x00\x17\x01' 2*4+1=9個字節(jié)

我們看上述三個使用例子(數(shù)據(jù)與數(shù)據(jù)之間沒有填充,都是連續(xù)的,比如對于vac我們不知道 它是由兩個4字節(jié)無符號整型和一個布爾構(gòu)成,我們就無法取得正確的值),看fmt參數(shù):

‘>I'代表了以大端的字節(jié)順序打包一個4字節(jié)無符號整型數(shù)據(jù),所以后面只跟了一個無符號整型參數(shù)1255;

‘>II'代表了以大端的字節(jié)順序打包兩個4字節(jié)無符號整型數(shù)據(jù),所以后面跟了兩個個無符號整型參數(shù)1255和23;

‘>2I?'代表了以大端的字節(jié)順序打包兩個4字節(jié)無符號整型和一個布爾型數(shù)據(jù),所以后面跟了兩個個無符號整型參數(shù)1255、23和一個布爾值True。

注意'2I'和'II','4I'和'IIII','2?'和'??'是一樣的效果。

解包

通過struct的unpack(fmt, string)來實現(xiàn)對字符串的解包,fmt和打包的是完全一樣的,如下(返回的結(jié)果是一個元組):

vaa = struct.pack('>I', 1255) # vaa: '\x00\x00\x04\xe7'
vab = struct.pack('>II', 1255, 23) # vab: '\x00\x00\x04\xe7\x00\x00\x00\x17'
vaaa = struct.unpack('>I', vaa) # vaaa: <class 'tuple'>: (1255, )
vaba = struct.unpack('>II', vab) # vaba: <class 'tuple'>: (1255, 23)

進階使用

pack_into(fmt, buffer, offset, *args)

fmt參數(shù)和pack是一樣的,buffer參數(shù)是可寫的緩存區(qū),offset是寫入位置的偏移量,*args是需要寫入的數(shù)據(jù)。這個有什么用呢,我們想想這樣兩個情況,我們有兩個類型已經(jīng)打包好,我們想在這兩個已經(jīng)打包好的數(shù)據(jù)后面再添加一個數(shù)據(jù)打包;或者我們要打包的數(shù)據(jù)很多,我們不可能在pack中把所有需要打包的數(shù)據(jù)都通過參數(shù)傳遞給pack,那你的pack函數(shù)可能得寫成千上完個參數(shù)了。這時候我們就可以用到這個函數(shù)了。

要使用它必須要一個可以寫入的緩存區(qū),我們可以導入一個字符緩存區(qū)包,然后創(chuàng)建一個固定大小的緩存區(qū)(以字節(jié)為單位):

import struct
from ctypes import create_string_buffer

# 創(chuàng)建一個9字節(jié)大小的緩存區(qū),初始化默認全部為\x00 
buf = create_string_buffer(9) # buf.raw: '\x00\x00\x00\x00\x00\x00\x00\x00\x00'

# 沖緩存區(qū)buf的第0個字節(jié)開始打包兩個4字節(jié)無符號整型數(shù)據(jù)1和2
struct.pack_into(">II", buf, 0, 1, 2) # buf.raw: '\x00\x00\x00\x01\x00\x00\x00\x02\x00'
# 然后我們想再打包一個布爾型數(shù)據(jù)到buf中就可以改變以下偏移量
struct.pack_into(">?", buf, 8, True) # buf.raw: '\x00\x00\x00\x01\x00\x00\x00\x02\x01'

unpack_from(fmt, buffer, offset)和calcsize(fmt)結(jié)合解包數(shù)據(jù)

calcsize用于計算格式字符串所對應的結(jié)果的長度,如:struct.calcsize(‘II'),返回8。因為兩個無符號整型所占用的長度是8個字節(jié)。unpack_from(fmt, buffer, offset)用于從buffer緩存區(qū)中使用fmt格式從offset偏移量處開始解包fmt里對應數(shù)量的數(shù)據(jù)。

import struct
from ctypes import create_string_buffer

buf = create_string_buffer(9)
struct.pack_into(">II", buf, 0, 1, 2)
struct.pack_into(">?", buf, 8, True)
# 記錄位置
pos = 0
# 從buf緩存區(qū)中以大端方式從偏移位置pos處解包兩個無符號整型數(shù)據(jù)返回,注意
#返回值如果只寫一個則返回一個元組,否則你解包幾個數(shù)據(jù)就要寫幾個返回值。
val = struct.unpack_from('>II', buf, pos) # val: <class 'tuple'>: (1, 2)
val_a, val_b = struct.unpack_from('>II', buf, pos) # val_a: 1 val_b: 2

# 重置解包位置
pos += struct.calcsize('>II') # pos: 8
val_c, = struct.unpack_from('>?', buf, pos) # val_c: True

示例

這個示例是基于mnist手寫數(shù)字識別的,我們剛開始有60000張手寫數(shù)字的圖片(.bmp格式的),我們通過下述代碼將60000張圖片轉(zhuǎn)換成字節(jié)型數(shù)據(jù),bytes.py代碼如下:

import struct
import os
import numpy as np
from ctypes import create_string_buffer
import cv2

# 創(chuàng)建一個60000 * 784 * 1 + 3 * 4字節(jié)大小的緩存區(qū),初始化默認全部為\x00
buffer = create_string_buffer(60000 * 784 * 1 + 3 * 4)
def writeBytesData():
 index = 0
 BMP_NUM = 0
 BMP_WIDTH = 28
 BMP_HEIGHT = 28

 # 先保留三個無符號整型的緩存區(qū)
 index += struct.calcsize('>III')
 path = 'data/bmp'
 if not os.path.exists(path):
  print('No this dir!')
  return
 list = os.listdir(path)
 for line_bmp in list:
  bmp_path = os.path.join(path, line_bmp)
  if os.path.isdir(bmp_path):
   print('This is not a .bmp')
  else:
   BMP_NUM += 1
   print(BMP_NUM)
   buf = cv2.imread(bmp_path, cv2.IMREAD_GRAYSCALE)
   buf = np.reshape(buf, [784])
   for pos in range(buf.__len__()):
    struct.pack_into('>B', buffer, index, buf[pos])
    index += struct.calcsize('>B')

 # 將保留緩存區(qū)的內(nèi)容填上
 struct.pack_into('>III', buffer, 0, BMP_NUM, BMP_WIDTH, BMP_HEIGHT)
 with open('data/bytes/bytes.bytes', 'wb') as fp:
  fp.write(buffer)


def readFromBytes():
 index = 0
 images = []
 with open('data/bytes/bytes.bytes', 'rb') as fp:
  buffer = fp.read()
  # 解包前三個無符號整型
  bmp_num, bmp_width, bmp_height = struct.unpack_from('>III', buffer, index)

  # 重定位偏移量
  index += struct.calcsize('>III')
  for pos in range(bmp_num):
   img = struct.unpack_from('>784B', buffer, index)
   index += struct.calcsize('>784B')
   # 修改為原來的圖片形狀
   img = np.array(img, dtype=np.uint8)
   img = np.reshape(img, [bmp_height, bmp_width])
   # 顯示圖片
   cv2.imshow('bmp', img)
   # 按任意鍵繼續(xù)
   cv2.waitKey(0)
   images.append(img)
 return images


writeBytesData()
readFromBytes()

在寫入bytes文件的時候有點慢,由于有60000張圖片每張要寫28 * 28個字節(jié),其中目錄結(jié)構(gòu)如下,需要圖片的可以去我的下載區(qū)下載mnist圖片數(shù)據(jù)集:

bytes.py
data
 bmp
  1.bmp
  2.bmp
  ...
  60000.bmp
 bytes

以上這篇python中struct模塊之字節(jié)型數(shù)據(jù)的處理方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • python設計模式之單例模式你了解多少

    python設計模式之單例模式你了解多少

    這篇文章主要為大家詳細介紹了python設計模式之單例模式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • python正則爬取某段子網(wǎng)站前20頁段子(request庫)過程解析

    python正則爬取某段子網(wǎng)站前20頁段子(request庫)過程解析

    這篇文章主要介紹了python正則爬取某段子網(wǎng)站前20頁段子(request庫)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • Matplotlib條形圖之分組條形圖和堆疊條形圖詳解

    Matplotlib條形圖之分組條形圖和堆疊條形圖詳解

    這篇文章主要為大家詳細介紹了Matplotlib條形圖之分組條形圖和堆疊條形圖,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Python的Flask框架中的Jinja2模板引擎學習教程

    Python的Flask框架中的Jinja2模板引擎學習教程

    這篇文章主要介紹了Python的Flask框架中的Jinja2模板引擎學習教程,Jinja2模板引擎的用法也是Flask的Web開發(fā)中的重要知識,需要的朋友可以參考下
    2016-06-06
  • python查詢mysql,返回json的實例

    python查詢mysql,返回json的實例

    下面小編就為大家分享一篇python查詢mysql,返回json的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Python 私有屬性和私有方法應用場景分析

    Python 私有屬性和私有方法應用場景分析

    這篇文章主要介紹了Python 私有屬性和私有方法應用場景分析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • python中(負數(shù))整除和取模運算方式

    python中(負數(shù))整除和取模運算方式

    Python中的取模運算符是%,它與其他語言中的取余符號相同,整除運算符是//,表示向下取整,在Python中,正數(shù)的取余和取模結(jié)果相同,但負數(shù)的取余和取模結(jié)果有所不同,取余運算在計算時向0方向舍棄小數(shù)位,而取模運算向負無窮方向舍棄小數(shù)位
    2024-10-10
  • Python 中Operator模塊的使用

    Python 中Operator模塊的使用

    這篇文章主要介紹了Python 中Operator模塊的使用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2021-01-01
  • Django保護敏感信息的方法示例

    Django保護敏感信息的方法示例

    這篇文章主要介紹了Django保護敏感信息的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • 深度學習環(huán)境搭建anaconda+pycharm+pytorch的方法步驟

    深度學習環(huán)境搭建anaconda+pycharm+pytorch的方法步驟

    本文主要介紹了深度學習環(huán)境搭建anaconda+pycharm+pytorch的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論

探索| 砚山县| 灵台县| 武威市| 临江市| 合作市| 丹东市| 富顺县| 沛县| 芜湖县| 彩票| 连州市| 神池县| 雅江县| 沙湾县| 乾安县| 云梦县| 玛曲县| 西乡县| 包头市| 武安市| 涿州市| 土默特左旗| 宾阳县| 北流市| 巫山县| 黔西县| 拜城县| 丹寨县| 喀喇| 北安市| 资源县| 靖西县| 旺苍县| 濮阳市| 南丰县| 长乐市| 舟山市| 宣恩县| 施秉县| 武川县|