본문 바로가기

Programming/Python Tutorials

[PYTHON 3] Tutorials 45. Struct (bytes data <-> normal data(human readable))


안녕하세요. 이번 시간에는 Struct 에 대해서 알아보도록 하겠습니다. 파이썬에서 Struct이 무엇인지부터 얘기를 시작해볼까 합니다. 파이썬에서는 어떠한 형태의 데이터, 가령 numbers, letters, string 와 같은 데이터를 bytes (0,1 으로 이루어진 바이너리 형태의 데이터) 데이터로 converting 할 수 있습니다. 그럼 왜 이렇게 bytes 형태의 데이터로 전환을 할까요? 이는 우리가 사용하는 컴퓨터가 데이터를 저장하거나 네트워크를 통해 이러한 데이터를 주고 받을 때, 이진형태의 bytes data( 0, 1 )로 데이터를 다루기 때문입니다. 그러나 이런 형태의 데이터는 인간이 확인하여 인지하기는 힘든 점이 있습니다. 그러므로 평소에는 인간들이 읽을 수 있는 형태로 스크린에 보여지지만, 이를 컴퓨터가  처리하기 위해 이진형태의 데이터로 연산(처리)를 한 이후, 다시 인간이 결과값을 확일할 때에는 다시 human readable data로 전환을 해 주어야 합니다. 이와 같은 일련의 과정을 프로그래밍적으로 다룰줄 알아야 raw data로 응용하여 다른 형태의 프로그램을 만드는데 유용하게 사용할 수 있습니다. 가령 네트워크 프로그램을 만드려고 한다고 하면, 이러한 raw data를 받아서 이 안에 어떤 값들이 있는지 사람들이 확인할 수 있게 변환을 해 주어야 하는데, 이럴 때 파이썬에서 사용하는 것이 Struct 라고 할 수 있습니다. 아주 간단하게 얘기하자면 이 정도가 python 에서 struct 가 가지는 의미라고 할 수 있습니다. 그럼 기본적인 코딩을 시작 해 보도록 하겠습니다.


아래와 같이 모듈을 불러옵니다. ▼


pack() 메소드를 사용할 예정입니다. 이 때 pack() 은 pack( 사용하고자 하는 포맷(fmt) ,  값들(values)) 과 같은 형태로 사용이 됩니다. 괄호 안의 i 는 integer(정수형), f 는 float(실수형) 이라는 의미입니다. 즉, 하위 코드는 5, 34, 34,00 이라는 세 개의 숫자를 정수형, 정수형, 실수형으로하는 바이너리(0,1로 이루어진) 데이터로 전환하겠다는 의미입니다. 이를 packed_data 라는 변수에 저장을 하고 출력을 하게 하였습니다. 

이제 5, 34, 34.00 을 바이너리 데이터로 저장을 하였으니, 출력을 해서 확인을 해봐야겠지요? 실행을 시켜보면 아래와 같은 결과가 나타납니다. 앞에 b'.......................'  라고 표기된 부분은 bytes형태라는 의미입니다.


아래 코드에서 calcsize() 는 괄호 안에 있는 데이터 포맷이 얼마만큼의 바이트 용량을 가지는지 알려주는 메소드 입니다. 'i' 는 정수형, 'f'는 실수형입니다. 아래 코드와 같이 입력후 실행을 하면 각각의 포맷이 가지는 바이트 할당량(메모리 지정량)이 결과로 나타나게 될 것입니다.


상기 코드의 결과는 아래와 같이 나타납니다. 정수형은 4 바이트, 실수형도 4바이트의 메모리를 차지하게 됩니다. 정수형,정수형,실수형 이렇게는 각각 4,4,4 바이트를 차지하므로, 도합 12바이트를 차지한다고 알려주고 있습니다.


pack() 이 바이트 데이터로 전환하게 한다면, 반대인 unpack() 는 bytes data 를 인간이 읽을 수 있는 형태의 데이터로 전환하게 하는 메소드 입니다. 아래 코드에서 packed_data 는 위에서 5,34,34.00 을 바이너리 데이터로 전환한 값입니다. 이제 이 값을 다시 human readable 데이터로 전환을 하면 당연히 5, 34, 34.00 으로 출력이 되어야 할 것입니다. 과정은 위와 같습니다. 다만 pack() 에 unpack()을 사용할 뿐 입니다. 


결과를 확인 해 보면 아래와 같습니다. 예상한 바와 같이 5, 34, 34.00 을 바이너리로 바꾸어 주었고, 다시 이 바이너리를 인간이 읽을 수 있는 형태의 데이터로 전환을 하니 본래의 값으로 돌아왔습니다. 


이번에는 처음부터 초기에 찾은 바이너리 데이터를 넣어보겠습니다. 그 값 역시 동일하게 나와야 할 것입니다. 아래와 같이 직접 바이너리 데이터를 넣어서 unpack() 을 실행하고 이 값을 프린트 아웃하겠습니다. 예상하신대로 동일한 값이 나와야겠지요? 실행을 해 보겠습니다. 


네. 결과가 동일하게 나오는 군요. 


한가지 첨언을 하자면, 위에서 실수형 값으로 34.00 을 넣어 주었는데, 만약 34.55 와 같이 소숫점 아래 값을 다른 값으로 넣으면 위의 코드에서와 같이 깔끔하게 딱 떨어지는 34.0 이라는 결과가 도출되지는 않을 것입니다. 이는 컴퓨터에서는 실수형 데이터를 처리할 때 부동 소수점 연산을 하는 방식이 각 프로그래밍 언어마다 조금씩 상이하기 때문입니다. 만약 소숫점 셋째 자리에서 반올림하는 것과 소숫점 15번째 값에서 반올림해 주는 것은 천냥지차일 것입니다.