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
댓글
댓글 쓰기