Post

(python) 출력 관련 - 문자열, str <> bytes, bytearray

str과 bytes-like object

문자열을 bytes로 만들고 싶다면 이 방법이 제일 간단하기는 하다.

1
a = b'string to byte'

b'\x80' 으로 직접 지정하면 \x80 이상 data도 입력할 수 있다.

파이썬에서 str형은 유니코드를 의미한다. 그래서 ASCII 문자열/바이트 문자열(bytes-like object)을 사용하는 부분에서 문제가 발생하곤 한다. 문자열을 byte 형식으로 변환하고 싶다면 인코딩 해야 한다.

1
2
str |  → → → → encode() → → → → | ASCII
    |  ← ← ← ← decode() ← ← ← ← |
1
2
3
>>> a = 'string to byte'
>>> a.encode()
b'string to byte'

encode()에 아무것도 지정하지 않으면 'utf-8'이 지정된다. UTF-8 인코딩은 ASCII range(127 = 0x7f)까지만 1 bytes로, 나머지는 2-4 bytes로 표기하도록 되어 있기 때문에 \x80 ~ \xff\xc2\x80 같이 두 개로 쪼개진다.

2017/06/05 - [Coding/etc] - Encoding 정리. Unicode, ANSI, UTF, CP949

1
2
3
4
5
>>> s = "\xff"
>>> s
'ÿ'
>>> s.encode()
b'\xc3\xbf'

ÿ 는 Unicode table에서 찾아보면 U+00FF이고, UTF-8 encoding table에서 찾아보면 \xc3\xbf이다.

bytes와 bytearray의 차이
  • bytes : immutable sequence of integers in range 0<=x<256
  • bytearray : mutable sequence of integers in range 0<=x<256

문자열 처리 지원 연산자

multiline string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from textwrap import dedent

applescript = dedent("""
    display dialog "HIT" ¬
    with title "HHHHHIIIIITTT!" ¬
    with icon caution ¬
    buttons {"OK"}
    """)

## \를 쓰면 개행 제거
a = """\
테스\
"""
복사 copy

x[:]

delimiter.join(list) : list를 문자열로

".".join(list) 하면 리스트 요소들 사이에 .이 들어간다.

split() : 문자열을 list로

널문자가 뒤에 붙는 문자열 처리 등 특정 문자를 만나면 그 이후를 버릴 때도 그냥 이걸 사용한다. rstrip()함수가 있기는 한데 이게 '\x00'같은거 집어넣으면 잘 동작하지 않는다. 반면 split()은 잘 동작한다.

1
2
string.split(sep[, maxsplit])
lfnName(e).split('\x00', 1)[0]

마지막 인자인 maxsplit을 지정해주면 성능도 괜찮을 것 같다.

len(), replace(), find(), index()

위치를 반환하는 함수로 find, index를 사용할 수 있는데 index는 문자를 못찾으면 오류 를 발생시키고 find는 문자를 못찾으면 -1을 리턴 한다.

old 문자열 포매팅 %
1
fmstr = '%s(%d) degree' % (dstr, i)

%s는 조금 특별한데, %s를 사용하면 어떤 타입이든 받을 수 있다. 자동으로 문자열로 변환해서 받게되기 때문. C에서는 변수 타입도 그렇고 포인터로 넘겨야 하니까 이게 불가능했지만, 파이썬에서는 변수 타입이 동적으로 결정돼 이렇게 사용할 수 있다.

고급 포매팅 {}
1
2
highfm = "I {0} you {1}"
print(highfm.format('like', 'too'))
  • 타입 신경 안써도 돼서 편리함.
  • 일단 문자열에 {0} 입력해 놓고 필요할 때 format() 호출해서 변수를 포맷스트링에 넣을 수 있음.
  • 형식 지정자를 사용하는 기존 방식도 지원. % 해도 됨.
  • {name} 이름으로 지정하는 것도 가능함.
1
2
"I ate {number} apples. so I was sick for {day} days.".format(number=10, day=3)
=> 'I ate 10 apples. so I was sick for 3 days.'
1
2
"{0:<10}".format("hi")
=> 'hi        '
  • 왼쪽 정렬(:<) 및 자리수 10칸 확보
  • 가운데 정렬(:=^10) 및 자리수 공백을 =으로 채우기
1
2
>>> "+{0:0>2}:{1:0>2}".format(hours, minutes)
'+09:00'

2칸 확보하고 오른쪽 정렬에 남는 공간은 0으로 채우기.

String Interporlation f-str (python 3.6+)
1
f"asdf {name}"
1
2
3
4
5
6
Yes: x = a + b
     x = '%s, %s!' % (imperative, expletive)
     x = '{}, {}'.format(first, second)
     x = 'name: %s; score: %d' % (name, n)
     x = 'name: {}; score: {}'.format(name, n)
     x = f'name: {name}; score: {n}'  # Python 3.6+
1
2
3
4
No: x = '%s%s' % (a, b)  # use + in this case
    x = '{}{}'.format(a, b)  # use + in this case
    x = first + ', ' + second
    x = 'name: ' + name + '; score: ' + str(n)
반복문에 print()sleep()이 같이 있는 경우 buffer를 flush해주어야 루프 마다 출력
1
2
while True:
    print('asdf', end='', flush=True)
pprint()
1
2
from pprint import pprint
pprint(var)
  • 알아서 깔끔하게 출력
list 안에 들어있는 객체 print 시 주소가 아니라 값들 출력하게 하려면, __repr__을 override
1
2
def \_\_repr\_\_(self):
return "[{} ({},{}) {} {}]".format(self.n, self.x, self.y, self.left, self.right)
This post is licensed under CC BY 4.0 by the author.