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