Python의 구조체 모듈
그만큼 구조체 모듈 ~에 파이썬 Python 값과 C 스타일 바이너리 데이터 간에 변환하는 기능을 제공하여 바이너리 데이터로 작업할 수 있습니다. 이는 바이너리 파일 형식이나 네트워크 프로토콜을 처리할 때 특히 유용합니다. 주요 기능은 다음과 같습니다.
- 포장 Python 값을 이진 데이터(바이트)로 변환합니다.
- 포장 풀기 바이너리 데이터를 다시 Python 값으로 변환합니다.
- 문자열 형식 지정 형식 코드를 사용하여 데이터를 압축/압축 해제하는 방법을 정의합니다(예: 정수의 경우 i, 부동 소수점의 경우 f).
struct.pack()의 메소드
1.구조체.팩(): Python 값을 압축된 바이너리 형식으로 변환합니다. 형식 문자열(fmt)은 압축된 데이터의 레이아웃을 지정하고 후속 값(v1 v2 ...)은 이 형식에 따라 압축됩니다. 통사론:
struct.pack(fmt v1 v2 ...)
- fmt : 데이터 압축 방법을 지정하는 형식 문자열입니다.
- v1 v2 ...: 지정된 형식에 따라 압축될 값입니다.
import struct # pack values into binary var = struct . pack ( 'hhl' 1 2 3 ) print ( var ) var = struct . pack ( 'iii' 1 2 3 ) print ( var )
산출
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'
설명: 'hhl' 두 개의 짧은 정수(h는 각각 2바이트) 뒤에 긴 정수(l은 플랫폼에 따라 일반적으로 4 또는 8바이트)가 오는 것을 의미합니다. 'iii' 세 개의 4바이트 정수를 팩합니다. 출력은 값의 이진 인코딩을 나타내는 바이트(b'') 단위입니다.
2.struct.unpack(): 압축된 이진 데이터를 다시 Python 값으로 변환합니다. 형식 문자열(fmt)과 압축된 이진 문자열을 사용하고 압축 해제된 값의 튜플을 반환합니다. 통사론:
struct.unpack(fmt 문자열)
- fmt: 데이터의 압축을 풀어야 하는 방법을 지정하는 형식 문자열입니다.
- 끈: 압축을 풀어야 하는 압축된 이진 데이터입니다.
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 )
산출
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)
설명: 이 예에서는 먼저 부울(?), 짧은(h), 정수(i) 및 긴(l)을 바이트로 압축합니다. 그런 다음 struct.unpack()을 사용하여 이를 Python 값으로 다시 변환합니다. 두 번째 부분은 긴 정수(q)와 부동 소수점(f)을 팩한 다음 다시 언팩합니다. 부동 소수점 정밀도로 인해 2.3이 어떻게 2.299999952...가 되는지 참고하세요.
3. 구조체.calcsize(): 형식 문자열에 해당하는 구조체의 크기(바이트)를 반환합니다. 압축된 데이터를 저장하는 데 필요한 공간을 결정하는 데 도움이 됩니다. 통사론:
구조체.calcsize(fmt)
- fmt: 데이터 레이아웃을 지정하는 형식 문자열입니다.
import struct print ( struct . calcsize ( '?hil' )) print ( struct . calcsize ( 'qf' ))
산출
16 12
설명: '?hil' 16바이트가 필요하며 'qf' 정렬 및 플랫폼에 따라 12바이트가 필요합니다.
4. struct.pack_into() 및 struct.unpack_from(): 이러한 메서드를 사용하면 주어진 오프셋에서 시작하는 버퍼에 데이터를 직접 압축하거나 압축을 풀 수 있습니다. 이는 미리 할당된 메모리 버퍼를 처리하거나 메모리에 저장된 이진 데이터로 작업할 때 특히 유용합니다.
struct.pack_into() 구문:
struct.pack_into(fmt 버퍼 오프셋 v1 v2 ...)
- fmt: 데이터 레이아웃을 지정하는 형식 문자열입니다.
- buffer: 쓰기 가능한 버퍼(예: ctypes.create_string_buffer).
- offset: 패킹이 시작되는 버퍼의 시작 위치입니다.
- v1 v2 ...: 버퍼에 압축할 값입니다.
struct.unpack_from() 구문:
struct.unpack_from(fmt 버퍼 오프셋=0)
- fmt: 데이터 레이아웃을 지정하는 형식 문자열입니다.
- 완충기: 압축된 데이터가 포함된 버퍼입니다.
- 오프셋: 포장 풀기가 시작되는 시작 위치(선택 사항)
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 )
산출
(2 2 3)
설명: 여기서는 ctypes를 사용하여 버퍼가 생성됩니다. struct.pack_into() 이 버퍼의 지정된 오프셋(이 경우 0)에 값을 삽입합니다. struct.unpack_from() 그런 다음 버퍼에서 데이터를 다시 읽습니다.
형식 순서의 효과
형식 문자의 순서는 패딩 및 정렬로 인해 압축된 출력을 변경할 수 있습니다. 이는 결과의 바이트 내용과 크기 모두에 영향을 미칩니다.
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' ))
산출
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5
설명: 'bi'(바이트 정수) 바이트 뒤에 패딩이 포함될 수 있지만 'ib'(정수 바이트) 필요하지 않습니다. 크기 차이(8 대 5)는 정렬이 메모리 레이아웃에 어떤 영향을 미치는지 보여줍니다.
오류 처리
struct.pack()에 잘못된 데이터 유형을 사용하면 struct.error가 발생합니다. 이러한 경우를 안전하게 처리하려면 try-Exception을 사용하세요.
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 } ' )
산출
Struct Error: required argument is not an integer
설명: 이는 구조체를 사용할 때의 오류 처리를 보여줍니다. 'h'에는 짧은 정수가 필요하지만 문자열('잘못됨')이 제공되어 struct.error가 발생합니다. Try-Exception 블록은 오류를 캡처하고 의미 있는 메시지를 인쇄합니다.
참조 https://docs.python.org/2/library/struct.html
퀴즈 만들기