2.5. 문자열 메서드와 포매팅

문자열에는 검사와 재구성을 위한 메서드 도구 상자가 기본 내장되어 있습니다. 문자열은 불변(immutable)이기 때문에 모든 메서드는 문자열을 반환하며, 원본은 변경되지 않습니다.

2.5.1. 문자열 검사하기

  • str.startswith() / str.endswith() – 접두사 또는 접미사 검사. bool 을 반환합니다.

  • str.find() – 부분 문자열이 처음 나타나는 위치, 없으면 -1. str.index() 는 동일한 일을 하지만 없을 경우 ValueError 를 발생시킵니다.

  • str.count() – 겹치지 않는 출현 횟수.

  • in 키워드 – "MV" in name 은 부분 문자열이 문자열의 어디엔가 있으면 True 를 반환합니다.

>>> name = "OpenMV Cam"
>>> name.startswith("Open")
True
>>> name.find("MV")
4
>>> name.count("m")
1
>>> "Cam" in name
True

2.5.2. 정리와 대소문자

  • str.strip() – 앞뒤의 공백을 제거합니다. 문자들로 이루어진 문자열을 전달하면 사용자 지정 집합을 제거합니다(s.strip("/")).

  • str.lower() / str.upper() – 대소문자 변환.

  • str.replace() – 부분 문자열 치환.

>>> "  hello  ".strip()
'hello'
>>> "abc-123".replace("-", "_")
'abc_123'
>>> "OpenMV".lower()
'openmv'

2.5.3. 분할과 결합

  • str.split() – 구분 기호가 나타날 때마다 문자열을 리스트로 나눕니다(기본값: 임의의 공백 구간).

  • str.join() – 그 역으로, 일련의 문자열을 수신자를 구분 기호로 하여 이어 붙입니다. 이것은 여러 조각으로부터 긴 문자열을 만드는 효율적인 방법입니다.

>>> "1,2,3".split(",")
['1', '2', '3']
>>> "hello world".split()
['hello', 'world']
>>> ", ".join(["a", "b", "c"])
'a, b, c'

2.5.4. f-문자열

값을 문자열에 보간하는 가장 간단한 방법은 f-문자열입니다. 이는 f 가 접두사로 붙은 문자열 리터럴입니다. {} 안의 모든 표현식은 평가되어 삽입됩니다:

>>> name = "OpenMV"
>>> count = 42
>>> f"{name} saw {count} blobs"
'OpenMV saw 42 blobs'

중괄호 안의 콜론은 값이 어떻게 렌더링될지 제어하는 포맷 스펙(format spec)을 도입합니다:

  • {x:.2f} – 소수점 이하 2자리의 float.

  • {x:>10} – 10자리 폭 필드에서 오른쪽 정렬.

  • {x:<10} – 왼쪽 정렬.

  • {x:0>4} – 폭 4까지 앞쪽을 0으로 채움.

  • {x:#x}0x 접두사가 붙은 16진수.

  • {x:b} – 2진수 표현.

>>> f"pi is roughly {3.14159:.3f}"
'pi is roughly 3.142'
>>> f"reg = {0xAB:#x}"
'reg = 0xab'
>>> for i in range(3):
...     print(f"line {i:0>3}")
line 000
line 001
line 002

표현식 이름 뒤의 단일 = 는 이름과 값을 모두 출력합니다. 빠른 디버그 출력에 유용합니다:

>>> v = 3.14
>>> print(f"{v=}")
v=3.14

2.5.4.1. 정수 진법 변환

세 가지 내장 함수는 :b / :o / :x 포맷 스펙과 동일한 일을 하지만 변환된 문자열을 직접 반환합니다:

  • bin()"0b" 접두사가 붙은 2진법.

  • oct()"0o" 접두사가 붙은 8진법.

  • hex()"0x" 접두사가 붙은 16진법.

>>> hex(255)
'0xff'
>>> bin(10)
'0b1010'
>>> oct(8)
'0o10'

반대 방향, 즉 N진법 문자열을 다시 정수로 변환하는 것은 명시적인 진법과 함께 int 생성자를 사용합니다:

>>> int("ff", 16)
255
>>> int("0b1010", 2)         # the "0b" prefix is allowed
10

정수의 원시 문자열이 필요할 때(로그 줄, 설정 파일, 레지스터 덤프용) 이들을 사용하세요. 패딩, 폭이 필요하거나 같은 f-문자열 안에서 값을 다른 텍스트와 섞고 싶을 때는 포맷 스펙을 사용하세요.

2.5.5. 오래된 포매팅 방식

f-문자열이 권장되는 방식이지만, 두 가지 오래된 방식도 여전히 동작하며 기존 코드에 나타납니다:

str.format() – 템플릿 문자열의 .format() 메서드에 전달되는 위치 인수 또는 키워드 인수가 든 중괄호:

>>> "Hello, {}".format(name)
'Hello, OpenMV'
>>> "{0} + {0} = {1}".format(2, 4)
'2 + 2 = 4'
>>> "{name}: {value}".format(name="frames", value=42)
'frames: 42'

포맷 스펙({:.2f}, {:>10}, …)은 f-문자열에서와 동일하게 동작합니다. 유일한 차이는 값이 어디에서 제공되는가입니다.

% 포매팅(printf 방식) – 단일 % 연산자가 포맷 코드에 값을 코드 하나당 값 하나씩 치환합니다. 여러 값을 전달하려면 튜플로 전달합니다:

>>> "Hello, %s" % name
'Hello, OpenMV'
>>> "%d + %d = %d" % (2, 2, 4)
'2 + 2 = 4'
>>> "%.2f" % 3.14159
'3.14'

가장 흔히 쓰이는 타입 코드는 %s (문자열), %d (정수), %f (부동소수점), %x (16진수)입니다.

% 코드는 % 와 타입 문자 사이에 수정자를 가질 수 있습니다. 전체 형태는 %[flags][width][.precision]type 입니다:

  • width – 필드가 차지해야 하는 최소 문자 수. 더 짧은 값은 스페이스로 채워지고, 더 긴 값은 넘칩니다. %10d 는 10자리를 예약하고 숫자를 오른쪽 정렬합니다.

  • precision – 의미는 타입에 따라 다릅니다. float의 경우 소수점 이하 자릿수입니다. %.2f 는 소수점 두 자리를 제공합니다. 문자열의 경우 취할 최대 문자 수입니다(%.5s 는 다섯 자로 자릅니다).

  • 왼쪽 정렬- 플래그는 필드를 왼쪽에 둡니다. %-10d 는 숫자를 왼쪽에 두고 뒤에 스페이스를 붙입니다.

  • 0 채우기0 플래그는 (숫자 타입에 대해) 스페이스 대신 앞쪽을 0으로 채웁니다. %05d 는 다섯 자리까지 0으로 채웁니다.

  • 부호+ 플래그는 항상 숫자에 부호를 표시하며, 양수에는 + 를 표시합니다.

  • 대체 형식# 플래그. %x 의 경우 출력 앞에 0x 를 붙이고, %o 의 경우 0o 를 붙입니다.

플래그, 폭, 정밀도는 결합할 수 있습니다:

>>> "%10d" % 42
'        42'                 # width 10, space-padded, right-aligned
>>> "%-10d|" % 42
'42        |'                # width 10, left-aligned
>>> "%05d" % 42
'00042'                      # width 5, zero-padded
>>> "%8.2f" % 3.14159
'    3.14'                   # width 8, 2 decimal places
>>> "%08.2f" % 3.14159
'00003.14'                   # width 8, zero-padded
>>> "%+d" % 42
'+42'                        # explicit sign
>>> "%#06x" % 0xAB
'0x00ab'                     # 0x prefix, zero-pad to 6 chars total

두 오래된 방식 모두 f-문자열보다 읽기 느리고 오류가 발생하기 쉽습니다. 새 코드에서는 f-문자열을 사용하고, 기존 코드를 읽을 때 오래된 형태를 알아볼 수 있도록 하세요.