python struct example

본 포스트는 python의 struct 라이브러리의 api와 사용 예제를 싣고 있다.

what is python struct?

python의 struct는 c 구조체와 python bytes object 간 상호 변환을 지원하는 라이브러리로, 네트워크 상에서 데이터를 주고받을 때 편하게 사용할 수 있다. c 구조체가 저장되는 메모리 구조와 동일하게 하기 위해 필요시 패딩 바이트가 추가된다.

아래는 c 코드와 python에서의 struct가 저장되는 메모리 크기와 데이터를 비교 예이다.

c struct

struct test
{
short a;
long b;
short c;

};

int _tmain(int argc, _TCHAR *argv[])
{
test t = { 1, 2, 3 };

int len = sizeof(t);
printf("%d\n", sizeof(t));
unsigned char *pt = (unsigned char*)&t;
for (int i = 0; i < len; i++)
printf("0x%x ", pt[i]);

return 0;
}

실행 결과
12
0x1 0x0 0xcc 0xcc 0x2 0x0 0x0 0x0 0x3 0x0 0xcc 0xcc

python struct

import struct

pack_format = '@hlh0l'
t = struct.pack(pack_format,1,2,3)
print(struct.calcsize(pack_format))
print(t)

실행 결과
12
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'

python struct에서 32 비트 얼라인을 맞추기 위해 short 데이터 다음에 2 바이트 패딩이 들어간 것을 볼 수 있다. 그리고, 데이터 마지막 2 바이트의 패딩을 위해서 format에 '0l'을 추가해야 한다. 주의 하자. 


python struct api and example

  • struct.pack(format, v1, v2, ...)

주어진 format으로 v1, v2 ,.. 데이터가 들어간 bytes object를 반환한다. 지원하는 format는 아래 표와 같다.

a = struct.pack('@?bhi',True,1,2,3)
print(a)

b'\x01\x01\x02\x00\x03\x00\x00\x00'


  • struct.pack_into(format, buffer, offset, v1, v2, ...)

쓰기 가능한 buffer에 offset 부터 format의 형식대로 v1, v2,... 데이터를 채워 넣는다.

x = np.zeros(20,dtype=np.byte)
print('buffer          :',x)
struct.pack_into('@hhi',x,10,1,2,3)
print('pack_into result:',x)

buffer            : [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
pack_into result: [0 0 0 0 0 0 0 0 0 0 1 0 2 0 3 0 0 0 0 0]


  • struct.unpack(format, buffer)

format에 따라 buffer의 byte object를 각각의 데이터로 풀어 놓는다.

a = struct.pack('@8sii',b'ryan ',100,1)
print(a)
name,score,grade = struct.unpack('@8sii',a)
print(name.decode(),score,grade)

b'ryan\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00'
ryan    100 1


  • struct.unpack_from(format, buffer, offset=0)

버퍼의 offset부터 format에 따라 byte object를 각각의 데이터로 풀어 놓는다.

x = np.zeros(20,dtype=np.byte)
struct.pack_into('@hhi',x,10,1,2,3)
    
print(struct.unpack_from(pack_format,x,10))

(1, 2, 3)

    

  • struct.iter_unpack(format, buffer)

buffer의 byte object를 format에 따라 반복적으로 데이터로 풀어 놓는다.

y = np.zeros(20,dtype=np.byte)
pack_format = 'hh'
for offset in range(0,20,4):
    struct.pack_into(pack_format,y,offset,offset+1,offset+2)
print('packed:',y)
print('iter unpack:',[x for x in struct.iter_unpack(pack_format,y)])

packed: [ 1  0  2  0  5  0  6  0  9  0 10  0 13  0 14  0 17  0 18  0]
iter unpack: [(1, 2), (5, 6), (9, 10), (13, 14), (17, 18)]


  • struct.calcsize(format)

format으로 만들어질 byte object의 길이를 반환한다.

print('format @hhi size:',struct.calcsize('@hhi'))

4

댓글

이 블로그의 인기 게시물

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

딥러닝을 사용한 로또 번호 예측 실험

간단한 cfar 알고리즘에 대해

아두이노(arduino) 심박센서 (heart rate sensor) 심박수 측정 example code