yapı modülü içinde Piton Python değerleri ile C tarzı ikili veriler arasında dönüştürme işlevi sağlayarak ikili verilerle çalışmanıza olanak tanır. Bu özellikle ikili dosya formatları veya ağ protokolleri ile uğraşırken kullanışlıdır. Temel özellikleri şunları içerir:
- Ambalaj Python değerlerini ikili verilere (bayt) dönüştürün.
- Paketi açma ikili verileri tekrar Python değerlerine dönüştürün.
- Dizeleri Biçimlendir Biçim kodlarını kullanarak verilerin nasıl paketleneceğini/paketten açılacağını tanımlayın (örneğin, kayan noktalı sayılar için f tamsayıları için i).
struct.pack()'deki yöntemler
1.Struct.pack(): Python değerlerini paketlenmiş ikili formata dönüştürür. Format dizesi (fmt), paketlenmiş verilerin düzenini belirtir ve sonraki değerler (v1 v2 ...) bu formata göre paketlenir. Sözdizimi:
struct.pack(fmt v1 v2 ...)
- fmt : Verilerin nasıl paketleneceğini belirten bir biçim dizesi.
- v1 v2 ...: Belirtilen formata göre paketlenecek değerler.
import struct # pack values into binary var = struct.pack('hhl' 1 2 3) print(var) var = struct.pack('iii' 1 2 3) print(var)
Çıkış
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'
Açıklama: 'hhl' iki kısa tam sayı (her biri h 2 bayt) ve ardından bir uzun sayı (platforma bağlı olarak genellikle 4 veya 8 bayt) anlamına gelir. 'iii' üç adet 4 baytlık tam sayı içerir. Çıkış, değerlerin ikili kodlamasını temsil eden bayt (b'') cinsindendir.
2.struct.unpack(): Paketlenmiş ikili verileri tekrar Python değerlerine dönüştürür. Bir biçim dizesi (fmt) ve paketlenmiş bir ikili dize alır ve paketlenmemiş değerlerden oluşan bir dizi döndürür. Sözdizimi:
struct.unpack(fmt dizisi)
kobol programlama
- fmt: Verilerin paketinin nasıl açılması gerektiğini belirten bir biçim dizesi.
- sicim: Paketinin açılması gereken paketlenmiş ikili veriler.
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)
Çıkış
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)
Açıklama: Bu örnek ilk önce bir boolean (?), kısa (h), bir tam sayı (i) ve bir uzun (l) değerini baytlara paketler. Daha sonra onu tekrar Python değerlerine dönüştürmek için struct.unpack() kullanılır. İkinci kısım, uzun bir tamsayıyı (q) ve bir kayan noktayı (f) paketler ve ardından bunları geri açar. Şamandıra hassasiyeti nedeniyle 2,3'ün nasıl 2,299999952... haline geldiğine dikkat edin.
3. struct.calcsize(): Biçim dizesine karşılık gelen bir yapının boyutunu (bayt cinsinden) döndürür. Paketlenmiş verileri depolamak için ne kadar alanın gerekli olduğunu belirlemek açısından faydalıdır. Sözdizimi:
struct.calcsize(fmt)
- fmt: Veri düzenini belirten bir biçim dizesi.
import struct print(struct.calcsize('?hil')) print(struct.calcsize('qf'))
Çıkış
16 12
Açıklama: '?hil' 16 bayt gerektirir ve 'qf' hizalamaya ve platforma bağlı olarak 12 bayta ihtiyaç duyar.
4. struct.pack_into() ve struct.unpack_from(): Bu yöntemler, belirli bir konumdan başlayarak verileri doğrudan arabelleğe/arabellekten paketleyip açmanıza olanak tanır. Bunlar özellikle önceden tahsis edilmiş bellek tamponlarıyla uğraşırken veya bellekte saklanan ikili verilerle çalışırken kullanışlıdır.
akşam yemeği vs akşam yemeği zamanı
struct.pack_into()'nun sözdizimi:
struct.pack_into(fmt arabellek ofseti v1 v2 ...)
- fmt: Veri düzenini belirten bir biçim dizesi.
- arabellek: Yazılabilir bir arabellek (örn. ctypes.create_string_buffer).
- ofset: Tampondaki paketlemenin başladığı başlangıç konumu.
- v1 v2 ...: Ara belleğe paketlenecek değerler.
struct.unpack_from() için sözdizimi:
struct.unpack_from(fmt arabellek ofseti=0)
- fmt: Veri düzenini belirten bir biçim dizesi.
- tampon: Paketlenmiş verileri içeren arabellek.
- telafi etmek: Paketi açmanın başladığı başlangıç konumu (isteğe bağlı)
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)
Çıkış
(2 2 3)
Açıklama: Burada ctypes kullanılarak bir arabellek oluşturulur. struct.pack_into() değerleri belirtilen ofset seviyesinde bu arabelleğe ekler (bu durumda 0). struct.unpack_from() daha sonra verileri arabellekten geri okur.
ilkbaharda jpa
Biçim sırasının etkisi
Biçim karakterlerinin sırası, dolgu ve hizalama nedeniyle paketlenmiş çıktıyı değiştirebilir. Bu, sonucun hem bayt içeriğini hem de boyutunu etkiler.
Pythonimport 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'))
Çıkış
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5
Açıklama: 'bi' (byte int) bayttan sonra dolgu içerebilirken 'ib' (int bayt) buna ihtiyacı yok. Boyut farkı (8'e 5), hizalamanın bellek düzenini nasıl etkilediğini gösterir.
Hataları işleme
struct.pack() ile yanlış veri türü kullanılırsa struct.error oluşur. Bu tür durumları güvenli bir şekilde ele almak için try-hariç'i kullanın.
Pythonimport 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}')
Çıkış
Struct Error: required argument is not an integer
Açıklama: Bu, yapı kullanılırken hata işlemeyi gösterir. 'h' kısa bir tamsayı bekliyor ancak struct.error'a neden olan bir dize ("geçersiz") veriliyor. Try- Except bloğu hatayı yakalar ve anlamlı bir mesaj yazdırır.
Referans https://docs.python.org/2/library/struct.html