문자열과 바이트

1. 문자열

파이썬에서 문자열은 단일인용부호(') 혹은 이중인용부호(") 를 사용하여 표현한다.
예를 들어, 아래 표현은 s 라는 변수에 가나다 라는 문자열을 할당하는 것으로 동일한 표현이다.

s = '가나다'
s = "가나다"

만약 여러 라인에 걸쳐 있는 문자열을 표현하고 싶다면, ''' 또는 """ 처럼 3개의 인용부호를 사용한다.

s = '''아리랑
아리랑
아라리요
'''
print(s)

복수 라인 문자열을 한 라인으로 표현하고 싶다면, Escape Sequence (\n)를 사용하면 된다. 즉, 다음 표현은 위와 동일한 표현이다.

실제 리눅스나 Mac OS에서는 Newline이 \n으로 표현되지만, 윈도우즈에서 \r\n을 사용한다. 하지만, 파이썬에서는 Universal Newline이 지원되어 모든 OS에서 공히 \n을 사용한다.

s = '아리랑\n아리랑\n아라리요'
print(s)

물론 문자열에서 사용되는 Escape Sequence에는 타 언어와 비슷하게 여러 가지를 사용할 수 있다. 예를 들어 탭은 \t, 이중따옴표는 \", 백슬래쉬는 \\ 등과 같이 표현한다.

문자열 포맷팅

일정한 포맷에 맞춰 문자열을 조합하는 것을 문자열 포맷팅이라하는데, 문자열 포맷 템플릿 안에 대입값이 들어갈 자리를 지정해 두고 나중에 그 값을 채워 넣는 방식이다. 예를 들어, "답: %s" % "A" 와 같은 표현에서 % 앞 부분은 포맷 템플릿이고, % 뒤는 실제 대입할 값이다. 이때 % 를 포맷팅 연산자 (Formatting Operator)라 부른다. % 앞뒤로 각각 하나의 값만을 받아들이므로 만약 % 뒤의 값이 복수 개이면 튜플로 묶어주어야 한다.

p = "이름: %s 나이: %d" % ("김유신", 65)
print(p)
# 출력: 이름: 김유신 나이: 65

p = "X = %0.3f, Y = %10.2f" % (3.141592, 3.141592)
print(p)
# 출력: X = 3.142, Y =       3.14

% (Formatting Operator) 앞의 포맷 템플릿에는 %s, %d 등과 같이 대입값 형식을 지정해 주는데 이를 변환 지시어(Conversion Specifier)라 부른다. 아래 표는 Conversion Specifier 들의 의미를 설명한 것이다.

Conversion Specifier 의미
%s 문자열 (파이썬 객체를 str()을 사용하여 변환)
%r 문자열 (파이썬 객체를 repr()을 사용하여 변환)
%c 문자(char)
%d 또는 %i 정수 (int)
%f 또는 %F 부동소수 (float) (%f 소문자 / %F 대문자)
%e 또는 %E 지수형 부동소수 (소문자 / 대문자)
%g 또는 %G 일반형: 값에 따라 %e 혹은 %f 사용 (소문자 / 대문자)
%o 또는 %O 8진수 (소문자 / 대문자)
%x 또는 %X 16진수 (소문자 / 대문자)
%% % 퍼센트 리터럴

Conversion Specifier는 % 와 Conversion 문자(예: s, d, f) 사이에 전체 자릿수와 소숫점 뒤자리수를 지정할 수 있다. 예를 들어 %10.2f 는 전체 10자리이고 값이 적으면 앞에 빈칸을 채우게 되고, .2 는 소수점 2째 자리까지만 표시한다는 것을 의미한다. 만약 %-10.2f 처럼 마이너스로 표현하면 전체 10자리인데 왼쪽으로 정렬한다는 의미이다.

2. str (문자열 클래스)

문자열은 내부적으로 str 이라는 클래스 타입인데, 파이썬의 문자열은 기본적으로 유니코드이고, 한번 설정되면 다시 변경시킬 수 없는 Immutable 타입이다.

문자열은 인덱스를 사용하여 문자열 중 특정위치의 문자를 표현할 수 있다. 인덱스는 0로부터 시작하는데, 문자열 s 에 대하여 첫번째 문자는 s[0], 두번째 문자는 s[1] 과 같이 표현된다.

s = "ABC"
type(s)      # class 'str'
v = s[1]     # B
type(s[1])   # class 'str'

파이썬에는 C, C# 등에서 존재하는 문자(char) 타입이 존재하지 않는다. 따라서, 위의 예에서 s[1]의 타입이 char가 아닌 문자열 str 타입이 된다. 참고로 type(변수명)은 해당 변수의 타입을 리턴한다.

문자열을 표현할 때, r'문자열' 과 같이 사용하면, 이는 Escape Sequence를 표현하지 않고 Raw String을 직접 사용한다는 것을 의미한다. 예를 들어, 윈도우즈에서 파일경로를 간략히 표현하기 위해 아래와 같이 Raw String 표현을 사용할 수 있다.

path = r'C:\Temp\test.csv'
print(path)

3. 자주 사용되는 str 메서드

문자열 str 클래스에는 여러 유용한 메서드들이 제공되고 있는데, 이 중 흔히 사용되는 몇가지만 소개한다.

str.join()

우선 여러 개의 문자열을 하나로 결합하는 join() 메서드가 있는데, join() 메서드는 문자열을 결합하는데 사용되는 Separator를 join 메서드 앞에 사용한다. 아래 예제에 보듯이, 콤마를 사용하여 문자열 리스트 요소들을 결합할 수도 있으며, 또한 빈 문자열을 사용하여 문자열들을 결합하는 방법도 자주 사용된다.

s = ','.join(['가나','다라','마바'])
print(s)
# 출력: 가나,다라,마바

s = ''.join(['가나','다라','마바'])
print(s)
# 출력 : 가나다라마바
str.split()

split() 메서드는 join() 메서드의 반대로서 특정 separator를 기준으로 문자열을 분리하여 리스트를 리턴한다. 아래 예제에서 split() 메서드는 하나의 문자열을 콤마로 분리해서 3개의 요소를 갖는 리스트를 리턴한다.

items = '가나,다라,마바'.split(',')
print(items)
# 출력 : ['가나', '다라', '마바']
str.partition()

partition() 메서드는 문자열을 partition() 메서드의 첫번째 파라미터로 분리하여 그 앞부분(prefix), partition 분리자(separator), 뒷부분 (suffix) 등 3개의 값을 Tuple로 리턴한다. 아래 예제는 Dash (-) 로 문자열을 분리하여 3개의 값을 리턴하는 코드이다. 일반적으로 separator는 사용하지 않아서 _ 를 사용하였다.

departure, _, arrival = "Seattle-Seoul".partition('-')
print(departure)
# 출력 : Seattle
str.format()

마지막으로 str 클래스에서 가장 많이 사용되는 메서드 중의 하나로 format() 메소드를 들 수 있다. format() 메서드는 다양한 방식의 문자열 포맷팅을 지원하는데, 아래는 흔히 사용되는 3가지 방식을 예시하고 있다. 먼저 위치를 기준으로한 포맷팅은 {0},{1},... 등의 필드들을 format() 파라미터들의 순서대로 치환하게 된다. 두번째 필드명을 기준으로 한 포맷팅은 {name}, {age}와 같이 임의의 필드명을 지정하고 format() 파라미터에 이들 필드명을 사용하여 값을 지정하는 것이다. 그리고 세번째 인덱스 및 키 사용 방식은 Python 오브젝트가 format()의 파라미터로 지정되고, 포맷에서 이 오브젝트의 인덱스(컬렉션의 경우) 혹은 속성, 키 등을 이용하는 것이다.

# 위치를 기준으로 한 포맷팅
s = "Name: {0}, Age: {1}".format("강정수", 30)
print(s)  #출력: Name: 강정수, Age: 30

# 필드명을 기준으로 한 포맷팅
s = "Name: {name}, Age: {age}".format(name="강정수", age=30)
print(s) #출력: Name: 강정수, Age: 30

# object의 인덱스 혹은 키를 사용하여 포맷팅
area = (10, 20)
s = "width: {x[0]}, height: {x[1]}".format(x = area)
print(s) #출력: width: 10, height: 20

4. bytes (바이트 클래스)

bytes 클래스는 일련의 바이트들을 표현하는 클래스로서 bytes는 한번 설정되면 다시 변경할 수 없는 Immutable 타입이다. bytes 클래스와 비슷한 클래스로 bytearray 클래스가 있는데, 차이점은 bytearray는 바이트 객체의 요소를 변경할 수 있는 Mutable 타입이라는 점이다. bytearray 에 대한 용법은 [bytearray 바이트배열]에 설명되어 있다.

문자들을 바이트들로 표현하기 위해 b'문자들'과 같이 접두어 b를 앞에 붙인다. 이렇게 접두어 b를 붙여 바이트 리터럴을 만들때, 각 문자는 ASCII 코드를 갖는 문자로 처리된다.

str 타입의 문자열을 bytes 타입의 바이트들로 변경하기 위해 str 클래스의 인코딩 메서드 encode()를 사용한다. 반대로 bytes 타입의 바이트 객체을 str 타입의 문자열로 변경하기 위해 bytes 클래스의 디코딩 메서드 decode()를 사용한다. encode(), decode() 를 사용하여 문자열과 바이트들 간의 인코딩/디코딩을 할 때, 특별히 파라미터를 지정하지 않으면 디폴트 인코딩을 사용하지만, 필요시 어떤 인코딩 방식을 사용할 지를 지정할 수 있다. 예를 들어, encode("UTF-8")과 같이 UTF8 인코딩 방식을 사용하도록 지정할 수 있다.

s = "Hello"
b = s.encode()
print(b)    # b'Hello'
s2 = b.decode()  
print(s2)   # 'Hello'

# 특정 인코딩 방식을 지정한 경우
x = "안녕".encode("UTF-8")
y= x.decode("UTF-8")

문자열 안에서 유니코드값을 사용하려면, \u 에 이어 유니코드값을 적으면 된다. 아래 예제는 문자열 s1을 UTF-8 인코딩을 사용하여 바이트들로 변경하고, 이를 다시 문자열로 디코딩하는 예제이다.

bytes 안의 바이트들을 HEX 문자열로 변환하기 위해서는 hex() 메서드를 사용할 수 있다.

binaryBytes = b'Hello'
hexString = binarybytes.hex()
print(hexString)   # '48656c6c6f'

[참고] bytes 안의 각 바이트를 HEX 문자로 표현하는 바이트로 변환하기 위해서는 binascii 표준 라이브러리의 hexlify() 함수를 사용한다. 아래 예제에서 hexlify() 함수는 첫문자 H를 아스키 코드로 48로 변환하고, 두번째 문자 e는 65 로 변환한다. hexlify()는 각 바이트를 16진수 값으로 변환한 bytes 타입을 리턴한다. bytes 타입을 다시 문자열 str 타입으로 변환하기 위해서는 decode() 를 사용한다.

from binascii import hexlify

hex_bytes = hexlify(b'Hello')
print(hex_bytes)  # b'48656c6c6f' 

hex_str = hex_bytes.decode()
print(hex_str)    # 48656c6c6f   
Python 프로그래밍 실습

본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.