struct modulis Python
The struktūros modulis in Python leidžia dirbti su dvejetainiais duomenimis, suteikiant funkcionalumą konvertuoti Python reikšmes į C stiliaus dvejetainius duomenis. Tai ypač naudinga dirbant su dvejetainiais failų formatais arba tinklo protokolais. Tarp pagrindinių jo savybių yra:
- Pakavimas konvertuoti Python reikšmes į dvejetainius duomenis (baitus).
- Išpakavimas konvertuoti dvejetainius duomenis atgal į Python reikšmes.
- Formatuoti eilutes apibrėžkite, kaip duomenys supakuojami / išpakuojami naudojant formatų kodus (pvz., i sveikiesiems skaičiams f, kai slankiojasi).
Metodai struct.pack()
1.Struct.pack(): Jis konvertuoja Python reikšmes į supakuotą dvejetainį formatą. Formato eilutė (fmt) nurodo supakuotų duomenų išdėstymą, o tolesnės reikšmės (v1 v2 ...) supakuojamos pagal šį formatą. Sintaksė:
struct.pack(fmt v1 v2 ...)
- fmt : formato eilutė, nurodanti, kaip bus supakuoti duomenys.
- v1 v2...: Reikšmės, kurios bus supakuotos pagal nurodytą formatą.
import struct # pack values into binary var = struct . pack ( 'hhl' 1 2 3 ) print ( var ) var = struct . pack ( 'iii' 1 2 3 ) print ( var )
Išvestis
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'
Paaiškinimas: „hhl“ reiškia du trumpus sveikuosius skaičius (h 2 baitai), po kurių seka ilgas (l paprastai 4 arba 8 baitai, priklausomai nuo platformos). 'iii' supakuoti trys 4 baitų sveikieji skaičiai. Išvestis pateikiama baitais (b''), nurodant dvejetainį reikšmių kodavimą.
2.struct.unpack(): Jis konvertuoja supakuotus dvejetainius duomenis atgal į Python reikšmes. Ji paima formato eilutę (fmt) ir supakuotą dvejetainę eilutę ir grąžina neišpakuotų reikšmių eilutę. Sintaksė:
struct.unpack(fmt string)
- fmt: Formato eilutė, nurodanti, kaip duomenys turi būti išpakuoti.
- eilutė: Supakuoti dvejetainiai duomenys, kuriuos reikia išpakuoti.
import struct var = struct . pack ( '?hil' True 2 5 445 ) print ( var ) tup = struct . unpack ( '?hil' var ) print ( tup ) var = struct . pack ( 'qf' 5 2.3 ) print ( var ) tup = struct . unpack ( 'qf' var ) print ( tup )
Išvestis
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)
Paaiškinimas: Šis pavyzdys pirmiausia supakuoja loginį (?), trumpąjį (h) sveikąjį skaičių (i) ir ilgą (l) į baitus. Tada struct.unpack() naudojamas konvertuoti jį atgal į Python reikšmes. Antroji dalis supakuoja ilgą ilgą sveikąjį skaičių (q) ir plūdę (f), tada išpakuoja juos atgal. Atkreipkite dėmesį, kaip 2.3 tampa 2.299999952... dėl plūdės tikslumo.
3. struct.calcsize(): Jis grąžina formato eilutę atitinkančios struktūros dydį (baitais). Tai naudinga norint nustatyti, kiek vietos reikia supakuotiems duomenims saugoti. Sintaksė:
struct.calcsize(fmt)
- fmt: formato eilutė, nurodanti duomenų išdėstymą.
import struct print ( struct . calcsize ( '?hil' )) print ( struct . calcsize ( 'qf' ))
Išvestis
16 12
Paaiškinimas: „? reikia 16 baitų ir 'qf' reikia 12 baitų, priklausomai nuo suderinimo ir platformos.
4. struct.pack_into() ir struct.unpack_from(): Šie metodai leidžia tiesiogiai supakuoti ir išpakuoti duomenis į buferį arba iš jo, pradedant nuo nurodyto poslinkio. Tai ypač naudinga dirbant su iš anksto paskirtais atminties buferiais arba dirbant su dvejetainiais duomenimis, saugomais atmintyje.
struct.pack_into() sintaksė:
struct.pack_into(fmt buferio poslinkis v1 v2 ...)
- fmt: formato eilutė, nurodanti duomenų išdėstymą.
- buferis: įrašomas buferis (pvz., ctypes.create_string_buffer).
- poslinkis: pradinė padėtis buferyje, kur prasideda pakavimas.
- v1 v2 ...: reikšmės, kurios turi būti supakuotos į buferį.
struct.unpack_from() sintaksė:
struct.unpack_from(fmt buffer offset=0)
- fmt: Formato eilutė, nurodanti duomenų išdėstymą.
- buferis: Buferis, kuriame yra supakuoti duomenys.
- kompensuoti: Pradinė padėtis, nuo kurios prasideda išpakavimas (neprivaloma)
import struct import ctypes # Allocate buffer size = struct . calcsize ( 'hhl' ) buff = ctypes . create_string_buffer ( size ) # Pack into buffer struct . pack_into ( 'hhl' buff 0 2 2 3 ) # Unpack from buffer res = struct . unpack_from ( 'hhl' buff 0 ) print ( res )
Išvestis
(2 2 3)
Paaiškinimas: Čia buferis sukuriamas naudojant ctypes. struct.pack_into() įterpia reikšmes į šį buferį nurodytu poslinkiu (šiuo atveju 0). struct.unpack_from() tada nuskaito duomenis atgal iš buferio.
Formatavimo tvarkos poveikis
Formatavimo simbolių tvarka gali pakeisti supakuotą išvestį dėl užpildymo ir lygiavimo. Tai turi įtakos ir baitų turiniui, ir rezultato dydžiui.
Python import struct var = struct . pack ( 'bi' 56 0x12131415 ) print ( var ) print ( struct . calcsize ( 'bi' )) var = struct . pack ( 'ib' 0x12131415 56 ) print ( var ) print ( struct . calcsize ( 'ib' ))
Išvestis
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5
Paaiškinimas: „bi“ (baitas int) gali apimti užpildymą po baito, tuo tarpu „ib“ (int baitas) jo nereikia. Dydžių skirtumas (8 prieš 5) rodo, kaip lygiavimas veikia atminties išdėstymą.
Tvarkymo klaidos
Jei su struct.pack() naudojamas netinkamas duomenų tipas, įvyksta struct.error. Naudokite bandymą, išskyrus tai, kad tokiais atvejais tvarkytumėte saugiai.
Python import struct try : struct . pack ( 'h' 'invalid' ) # Wrong type 'invalid' is a string but 'h' expects an integer except struct . error as e : print ( f 'Struct Error: { e } ' )
Išvestis
Struct Error: required argument is not an integer
Paaiškinimas: Tai rodo klaidų tvarkymą naudojant struct. „h“ tikisi trumpo sveikojo skaičiaus, tačiau pateikiama eilutė („netinkama“), sukelianti struct.error. „Try-except“ blokas užfiksuoja klaidą ir išspausdina prasmingą pranešimą.
Nuoroda https://docs.python.org/2/library/struct.html
Sukurti viktoriną