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

댓글

이 블로그의 인기 게시물

base64 인코딩 디코딩 예제 c 소스

바로 프로젝트 적용 가능한 FIR Filter (low/high/band pass filter )를 c나 python으로 만들기

간단한 cfar 알고리즘에 대해

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

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