Skip to content
This page has been auto-translated and may contain errors.View in English

문자열

docs.scrimba.com

작성하는 거의 모든 프로그램에 텍스트가 나타납니다. 이름, 메시지, 점수, 레이블. Python에서 모든 텍스트는 문자열이라고 불립니다: 따옴표로 감싼 모든 값. 홑따옴표든 쌍따옴표든 둘 다 같은 방식으로 작동합니다.

문자열은 Python의 기본 텍스트 타입입니다. 사용자 이름부터 URL 경로까지 서식화된 출력까지 모든 것을 전달합니다. 홑따옴표와 쌍따옴표는 동일한 결과를 생성합니다. 선택은 스타일의 문제입니다.

str은 모든 시스템 경계에 있습니다: 터미널 I/O, 파일 콘텐츠, 네트워크 응답, 직렬화된 데이터. Python의 불변(생성 후 변경할 수 없는) 유니코드 시퀀스 타입입니다. 두 따옴표 스타일 모두 동일한 객체를 생성하므로 선택은 순전히 스타일입니다.

python
greeting = "Hello, world"
username = 'alice'

따옴표 선택이 중요한 유일한 경우는 텍스트에 따옴표가 포함될 때입니다. 반대 스타일을 사용하면 이스케이프할 필요가 없습니다:

커뮤니티 관례는 쌍따옴표입니다. 스타일을 바꾸는 실질적인 이유는 콘텐츠에 그 문자가 포함될 때 이스케이프를 피하기 위함입니다:

관례는 쌍따옴표이며, Black과 Ruff 같은 포매터는 자동으로 이를 적용합니다. 손으로 작성한 유일한 이유는 콘텐츠에 구분자가 포함될 때 백슬래시 이스케이프를 피하기 위함입니다:

python
note = "It's a great day"      # 아포스트로피 내부, 쌍따옴표 사용
message = 'She said "hello"'   # 쌍따옴표 내부, 홑따옴표 사용
escaped = "She said \"hello\""  # 또는 백슬래시로 이스케이프

불변성

문자열은 불변입니다: 한 번 생성하면 변경할 수 없습니다. 문자열을 생성되는 순간 영구적으로 고정된 것으로 생각하세요. 문자열을 수정하는 것처럼 보이는 모든 작업은 실제로 새로운 것을 생성합니다. 원본은 정확히 그대로 유지됩니다.

문자열은 불변입니다: 어떤 메서드도 제자리에서 문자열을 수정하지 않습니다. 텍스트를 변환하는 모든 작업은 새 문자열을 반환하고 원본은 그대로 둡니다. 실질적인 결과는 어디에도 할당하지 않은 메서드 호출이 아무것도 영향을 주지 않는다는 것입니다.

str 객체는 불변입니다. 즉, 한 번 생성되면 그 내용이 고정되고 아무것도 그들에게 쓸 수 없습니다. 이는 문자열에 두 가지 성질을 제공합니다: 그들은 해시 가능합니다 (내용이 절대 변하지 않는 값을 그 내용으로 분류할 수 있으며, 이것이 문자열이 딕셔너리 키나 집합 멤버로 작동하도록 합니다), 그리고 공유된 문자열이 누군가에 의해 변경될 수 없으므로 이름 간에 안전하게 전달할 수 있습니다.

python
name = "alice"
name = name.upper()   # "ALICE"는 새로운 문자열입니다; "alice"는 변경되지 않음

직접적인 결과: 특정 위치의 문자를 변경할 수 없습니다. 시도하면 Python이 오류를 발생시킵니다.

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

수정된 문자열을 얻으려면 슬라이싱이나 메서드를 사용하여 새로운 문자열을 만드세요. 둘 다 아래에서 다룹니다.

문자 할당을 시도하면 제약이 직접 표시됩니다:

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

수정된 버전이 필요하면 표준 도구는 위치 편집을 위해 슬라이싱과 연결을 사용하고, 대체를 위해 replace()를 사용합니다. 둘 다 새 문자열을 생성하고 원본은 그대로 둡니다.

위치에 할당하면 (name[0] = "A") 항상 TypeError를 발생시킵니다. 예외는 없습니다. 위치 편집의 경우 변경하려는 부분 주위를 슬라이싱하여 새 문자열을 만드세요: name[:1].upper() + name[1:]은 첫 번째 문자를 대문자로 만듭니다. 문자열의 어디에서나 대체하려면 replace()를 사용하세요.

Juno불변성 문자열은 존재하는 순간 절대 변경되지 않습니다. 편집하는 것처럼 보이는 모든 것은 대신 새 문자열을 돌려주므로 결과를 할당하거나 사라집니다. 초기에 나를 잡은 것: name[0] = "A"는 작동하지 않습니다. TypeError를 발생시킵니다.
Juno불변성 어떤 문자열 메서드도 제자리에서 편집하지 않습니다. 모든 것이 새 문자열을 반환하고 원본을 그대로 둡니다. 따라서 name.upper()는 그 자체로는 유용하지 않습니다. 할당해야 합니다. 그리고 name[0] = "A"TypeError를 발생시킵니다. 제자리에 문자 교환은 없습니다.
Juno불변성 불변성은 문자열을 해시 가능하게 만들어서 딕셔너리 키로 작동하고 복사 없이 공유하기에 안전합니다. 실질적인 결과: 모든 변환 메서드의 결과를 할당하세요. 아무것도 원본을 건드리지 않기 때문입니다. 위치 편집의 경우 위치 주위를 슬라이싱하고 다시 만드세요. 항목 할당은 항상 TypeError를 발생시키기 때문입니다.

인덱싱과 슬라이싱

문자열의 모든 문자는 0부터 시작하는 번호가 매겨진 위치를 가집니다. 그 위치 번호를 대괄호에 넣어 개별 문자를 읽을 수 있습니다. 음수는 끝에서 역순으로 계산합니다.

문자열은 0 기반 인덱싱이 있는 시퀀스입니다. 음수 인덱스는 끝에서 계산합니다. 슬라이싱은 단일 표현식에서 연속 범위를 추출하며, 범위를 벗어나는 값에 대해 오류를 발생시키지 않습니다.

문자열은 인덱싱하고 슬라이싱할 수 있는 정렬된 시퀀스처럼 작동합니다. 단일 위치를 읽으면 (s[i]) 인덱스가 끝을 넘으면 IndexError를 발생시킵니다. 슬라이싱 (s[start:stop:step])은 다르게 작동합니다: 범위를 벗어나는 경계는 자동으로 존재하는 것으로 고정되므로 슬라이싱은 IndexError를 발생시킬 수 없습니다. 그 차이가 실질적인 것입니다: 인덱스 접근은 엄격하고, 슬라이싱은 관대합니다.

python
word = "Python"
#       012345

print(word[0])    # "P"
print(word[2])    # "t"
print(word[5])    # "n"
print(word[-1])   # "n"  (마지막 문자)
print(word[-2])   # "o"  (끝에서 두 번째)

-1은 항상 마지막 문자, -2는 끝에서 두 번째이고, 등등입니다. 정확한 길이를 모르면서 문자열의 끝을 원할 때 유용합니다.

음수 인덱스는 래핑됩니다: -1len(s) - 1이고, -2len(s) - 2입니다. 길이를 수동으로 계산하지 않으려는 끝 앵커 접근에 가장 유용합니다. 범위를 벗어난 음수 인덱스는 양수와 동일하게 IndexError를 발생시킵니다.

음수 인덱스는 경계 검사 전에 len(s) + i로 변환되므로 -1은 마지막 문자에 도달하고 -2는 그 전 문자에 도달합니다. 범위를 벗어나면 양수 또는 음수 모두 IndexError를 발생시킵니다: 슬라이싱만 용서합니다. 평문 인덱싱은 그렇지 않습니다.

슬라이싱은 청크를 추출합니다. [start:stop]start를 포함하고 stop을 제외합니다:

python
word = "Python"

print(word[0:2])   # "Py"     (위치 0과 1)
print(word[2:])    # "thon"   (위치 2부터 끝)
print(word[:3])    # "Pyt"    (시작부터 위치 2)
print(word[:])     # "Python" (전체 문자열 복사)
print(word[::2])   # "Pto"    (모든 두 번째 문자)
print(word[::-1])  # "nohtyP" (역순)

대부분 사용할 세 가지 패턴: word[:n]은 처음 n개 문자, word[n:]은 위치 n부터 모든 것, word[-n:]은 마지막 n개 문자. word[::-1]은 문자열을 역순으로 만듭니다. 처음에는 이상해 보이지만 관례적인 Python이고 자주 보게 됩니다.

직접 인덱싱과 달리 슬라이싱은 IndexError를 발생시키지 않습니다. Python은 범위를 벗어난 인덱스를 자동으로 고정하므로 짧은 문자열에서 word[100:]은 충돌하기보다 ""를 반환합니다. 스텝 인수는 스트라이드를 제어합니다: word[::2]는 모든 다른 문자를 취하고, word[::-1]은 역순으로 순회합니다.

s[start:stop:step]에서 생략한 부분은 "가는 방향의 자연스러운 끝"으로 기본값이 설정되며, 고정된 0len()이 아닙니다. 양수 스텝에서 그것은 시작부터 끝을 의미합니다. 음수 스텝에서 뒤집어집니다. 그래서 start는 마지막 문자가 되고 stop은 앞에서 떨어집니다. 이것이 s[::-1]이 어떤 경계도 쓰지 않고 전체 문자열을 역순으로 걷는 이유이고, 같은 이유로 s[::-2]는 역순으로 모든 두 번째 문자를 제공합니다.

Juno인덱싱과 슬라이싱 위치는 0부터 시작하므로 word[0]은 첫 번째 문자이고 word[-1]은 마지막입니다. 슬라이스는 범위를 잡습니다: word[start:stop]start를 유지하고 stop 직전에 멈춥니다. word[::-1]은 문자열을 역순으로 만듭니다. 처음에는 이상하게 보이다가 영원히 사용합니다.
Juno인덱싱과 슬라이싱 0부터 인덱싱하거나, 음수로 끝에서 인덱싱하세요. word[-1]은 마지막 문자입니다. 슬라이스는 start를 포함하고 stop을 제외하는 범위를 취하고, 세 번째 step은 스트라이드를 설정합니다. 그래서 word[::-1]은 역순입니다. 기억할 함정: 끝을 넘어 인덱싱하면 IndexError를 발생시키지만 슬라이싱하면 대신 거기 있는 것을 반환합니다.
Juno인덱싱과 슬라이싱 평문 인덱싱은 엄격하고 범위를 벗어나면 IndexError를 발생시키고, 슬라이싱은 관대하며 존재하는 것으로 고정되므로 word[100:]은 발생시키기보다 ""를 반환합니다. 슬라이스 부분을 생략하면 스텝의 방향의 자연스러운 끝으로 기본값이 설정되며, 이것이 word[::-1]이 쓴 경계 없이 역순으로 문자열을 만드는 이유입니다. 빈 또는 짧은 입력에 충돌하지 않으려면 슬라이스에 도달하세요.

필수 문자열 메서드

문자열은 기본 제공 메서드 세트와 함께 제공됩니다: 모든 문자열 값에서 직접 호출하는 작업. 문자열(또는 그것을 보유한 변수)을 쓴 다음 점을 쓴 다음 메서드 이름을 씁니다. 각 메서드는 새 문자열을 반환합니다. 원본은 절대 변경되지 않습니다.

문자열 메서드는 str 타입에 연결된 함수입니다. 문자열이 불변이기 때문에 모든 메서드는 원본을 수정하기보다 새 문자열을 반환합니다. 어디에도 할당하거나 전달하지 않는 메서드 호출은 지속되는 영향이 없습니다.

모든 변환 메서드는 새 str을 반환하고 원본을 그대로 둡니다. 이것은 불변성에서 직접 따릅니다. 그들은 또한 코드 포인트(문자 자체, 그들을 저장하는 데 사용되는 원시 바이트가 아님)에서 작동합니다. 따라서 메서드는 당신이 특별한 것을 하지 않고도 악센트 및 비 라틴 텍스트에서 올바르게 작동합니다. 기억할 트레이드오프: 각 메서드는 새 문자열을 할당하므로 많은 메서드를 큰 텍스트에서 연결하면 많은 할당을 의미합니다.

경우

python
text = "Hello, World"

text.lower()       # "hello, world"
text.upper()       # "HELLO, WORLD"
text.title()       # "Hello, World"  (각 단어 대문자)
text.capitalize()  # "Hello, world"  (첫 단어만)

lower()upper()는 가장 많이 사용할 두 가지입니다. lower()는 텍스트 비교에 특히 유용합니다: "Alice""alice"는 양쪽에서 .lower()를 호출하면 같은 것이 됩니다.

lower()는 비교나 저장 전의 표준 정규화 단계입니다. title()은 축약형에서 오작동하는 대략적인 규칙을 사용하여 각 단어의 첫 글자를 대문자로 만듭니다: "it's""It'S"가 됩니다. 이를 디스플레이 전용 서식으로 취급하세요.

lower()는 유니코드 전체 경우 변환을 적용합니다. 대소문자를 구분하지 않는 비교의 경우 casefold()가 더 정확합니다: 추가 변환을 적용합니다(예: 독일어 ß는 ss가 됨). lower()는 건너뜁니다. title()은 모든 영숫자가 아닌 문자 뒤에 대문자로 만들어서 축약형과 하이픈이 있는 이름을 잘못 처리합니다. 올바른 제목 케이싱을 위해 논리를 수동으로 구현하세요.

공백

python
text = "  hello  "

text.strip()    # "hello"    (양쪽)
text.lstrip()   # "hello  "  (왼쪽만)
text.rstrip()   # "  hello"  (오른쪽만)

strip()은 문자열의 양쪽 끝에서 공백을 제거합니다. 사용자 입력이나 파일의 텍스트를 처리할 거의 모든 경우에 사용할 것입니다. 왜냐하면 여분의 공백은 조용한 실패를 유발하기 때문입니다: "alice" != "alice ".

strip()은 모든 선행 및 후행 공백을 제거합니다: 공백, 탭 및 줄 바꿈. 방향 변형은 한쪽만 청소하도록 하여 들여쓰기를 건드리지 않으면서 후행 줄 바꿈을 제거하는 데 유용합니다. 세 가지 모두 특정 문자를 대신 제거하기 위한 선택적 문자 인수를 허용합니다.

인수 없이 strip()은 끝에서 모든 종류의 공백을 제거합니다. 평문 공백뿐만 아니라 비 ASCII 공백을 포함합니다. 문자 인수를 사용하면 양쪽 끝에서 그 문자들을 제거합니다. 이것은 함정입니다: 인수는 일치할 접두사가 아니라 제거할 문자 세트입니다. "xxhelloxx".strip("x")"hello"를 반환하지만 "https://".strip("https")는 접두사 "https"를 제거하지 않습니다. 양쪽 끝에서 모든 h, t, ps를 제거하고 "://"를 반환합니다. 알려진 접두사 또는 접미사를 제거하려면 대신 removeprefix()removesuffix()를 사용하세요.

찾기

python
text = "Hello, world"

text.find("world")         # 7
text.find("Python")        # -1  (찾을 수 없음)
text.count("l")            # 3
text.startswith("Hello")   # True
text.endswith("world")     # True

find()는 텍스트가 문자열 내에서 시작하는 위치를 반환합니다. 그곳에 없으면 -1을 반환합니다. 문자열이 특정 문자로 시작하거나 끝나는지만 신경 쓸 때 startswith()endswith()를 사용하세요.

find()는 첫 번째 일치의 시작 인덱스를 반환하거나 -1을 반환합니다. -1 관례는 결과를 확인 없이 슬라이싱이나 산술에서 직접 사용할 수 있도록 합니다. startswith()endswith()는 각각 문자열 튜플을 허용하므로 한 호출에서 여러 접두사나 접미사를 테스트할 수 있습니다.

find()는 왼쪽에서 오른쪽으로 스캔하고 일치가 없으면 -1을 반환합니다. index()는 같은 검색을 수행하지만 -1을 반환하는 대신 ValueError를 발생시킵니다: 일치하지 않으면 코드에 버그가 있고 거기서 중지하고 싶으면 index()를 선택하세요. 부재가 정상 입력이고 당신이 확인할 경우 find()를 선택하세요. 순수한 "이것으로 시작하거나 끝나는가" 질문의 경우 startswith()endswith()가 의도를 나타내고 첫 불일치에서 멈추므로 그 작업을 위해 find()in 확인보다 선호하세요.

바꾸기

python
text = "Hello, world"

text.replace("world", "Python")   # "Hello, Python"
text.replace("l", "L")            # "HeLLo, worLd"  (모든 항목)
text.replace("l", "L", 1)         # "HeLlo, world"  (첫 번째만)

replace()는 한 텍스트 조각을 다른 텍스트로 교환하고 새 문자열을 반환합니다. 원본은 변경되지 않습니다. 첫 번째 항목만 바꾸려면 세 번째 인수를 전달하세요.

replace()는 기본적으로 모든 겹치지 않는 항목을 바꿉니다. 개수 인수는 몇 개가 바뀌는지 제한합니다. 새 문자열을 반환하므로 호출을 연결할 수 있습니다: text.replace("a", "A").replace("e", "E")는 두 대체를 순서대로 적용합니다.

replace()는 패턴이 아닌 리터럴 부분 문자열을 일치시키므로 정규식을 수행하지 않고 인수의 모든 문자를 있는 그대로 취급합니다. 왼쪽에서 오른쪽으로 겹치지 않는 일치를 바꾸며, 이는 당신을 놀라게 할 수 있습니다: "aaa".replace("aa", "b")는 두 번째 aa가 첫 번째 일치와 겹치기 때문에 "bb"가 아닌 "ba"를 제공합니다. 개수 인수는 몇 개를 바꾸는지 제한하고, 모든 호출이 새 문자열을 반환하므로 연결할 수 있습니다: text.replace(",", "").replace(" ", "_").

분할 및 결합

split()은 구분 기호에서 문자열을 조각으로 자르고 리스트로 반환합니다. 무엇을 자를지 알려주세요:

split()은 구분 기호에서 분할하고 세그먼트를 리스트로 반환합니다. 인수 없이 호출하면 모든 공백 실행에서 분할하고 여러 연속 공백에서 빈 문자열을 버립니다:

split(sep)은 왼쪽에서 오른쪽으로 스캔하고 sep의 모든 겹치지 않는 항목에서 분할합니다. 인수 없이 다른 알고리즘을 사용합니다: 공백 실행에서 분할하고 결과에서 선행 및 후행 공백을 제거합니다. rsplit(sep, n)은 오른쪽에서 분할하며 점으로 구분된 경로 또는 네임스페이스 식별자의 마지막 세그먼트를 격리하는 데 유용합니다.

python
csv_row = "Alice,28,Seoul"
parts = csv_row.split(",")     # ["Alice", "28", "Seoul"]

"  hello   world  ".split()   # ["hello", "world"]

split()은 리스트를 반환합니다. 값의 정렬된 시퀀스. 그들은 그들 자신의 Lists 장을 가집니다. 지금은 split()이 생성하는 부분 시퀀스와 join()이 사용하는 것으로 취급하세요.

join()은 반대를 합니다: 문자열 리스트를 하나로 결합합니다. 점 앞의 문자열은 각 항목 사이에 배치됩니다:

python
words = ["Hello", "world"]

" ".join(words)    # "Hello world"
", ".join(words)   # "Hello, world"
"".join(words)     # "Helloworld"

기억할 패턴: separator.join(list_of_strings). 구분 기호는 왼쪽에 가고 리스트는 오른쪽에 갑니다. " ".join(words)는 각 단어 사이에 공백을 넣습니다. "".join(words)는 아무것도 사이에 없이 접착합니다.

join()은 여러 조각에서 단일 문자열을 조합할 때마다 올바른 도구입니다. 각 단계에서 새 문자열을 만드는 대신 단일 할당을 수행합니다. 2개 또는 3개 문자열의 경우 +는 완벽하게 좋습니다. 상당한 크기의 리스트가 있으면 join()에 도달하세요.

join()은 조각을 한 번 이동하고 총 크기를 계산하고 결과를 한 번 할당하고 모든 것을 작성합니다. 반복된 +를 루프에서 같은 문자열을 만드는 것은 비싼 형태입니다. 문자열을 변경할 수 없으므로 각 +는 새 문자열을 할당하고 지금까지 모든 것을 복사하므로 비용은 부분 수의 제곱으로 증가합니다. 몇 개의 문자열에서 아무도 알아차리지 못하지만 몇 천 개에서는 빠른 작업을 느리게 만듭니다. 그것을 방지하는 규칙: 조각들을 리스트에 수집하고 끝에서 한 번 join()하세요. 루프에서 절대 문자열에 +=하지 마세요.

Juno필수 문자열 메서드 이들은 모두 새 문자열을 반환하므로 결과를 할당하거나 사라집니다. 매일 도달할 소수: 경우를 위해 .lower().upper(), 여분의 공백을 다듬기 위해 .strip(), 텍스트를 찾기 위해 .find()(불완전할 때 -1 반환), 텍스트를 교환하기 위해 .replace(), 문자열을 분해하고 다시 조합하기 위해 .split()sep.join().
Juno필수 문자열 메서드 이들 모두는 새 문자열을 반환하고 어떤 것도 변경하지 않으므로 연결하거나 할당하세요. 함정을 직진하게 유지하세요: .strip("x")는 접두사가 아니라 제거할 문자 세트를 취하고, .split()은 인수 없이 공백 실행을 축약합니다. 많은 부분을 조합하려면 리스트를 작성하고 sep.join()하세요.
Juno필수 문자열 메서드 실제 코드에서 물린 두 함정: .strip(chars)는 접두사가 아닌 문자 세트를 끝에서 제거하므로 접두사를 의도할 때 removeprefix()를 사용하세요. 루프에서 `+=`로 문자열을 작성하는 것은 느린 형태이므로 리스트로 수집하고 한 번 join()하세요. 비교를 위해 .lower()보다 .casefold()로 정규화하고 축약형을 손상시키므로 .title()을 디스플레이 전용으로 취급하세요.

f-문자열

f-문자열은 값을 텍스트 내부에 직접 포함합니다. 열기 따옴표 앞에 f를 넣은 다음 중괄호에 모든 변수 또는 표현식을 래핑하세요. Python은 코드가 실행될 때 채웁니다. 값 뒤에 콜론을 추가하여 표시 방식을 제어할 수도 있습니다.

f-문자열은 런타임에 {} 내의 모든 표현식을 평가하고 결과를 문자열로 변환합니다. 중괄호 내 콜론은 서식 사양을 시작합니다: 소수점 자리, 정렬 및 숫자 서식을 제어하는 ​​간단한 구문입니다.

f-문자열의 각 {}는 값의 자체 __format__ 메서드(Python이 값을 서식화할 때 백그라운드에서 호출하는 던더, 더블 언더스코어 메서드)를 호출하고 콜론 뒤에 작성한 모든 것을 전달합니다. 따라서 작성한 모든 클래스는 __format__을 정의하여 f-문자열 내부에 나타나는 방식을 결정할 수 있습니다. 변환 플래그 !r, !s!a는 먼저 repr(), str() 또는 ascii()를 값에서 실행합니다. !r은 유지할 것입니다. 코드에서 입력하는 방식으로 값을 보여주므로 인용문과 이스케이프를 포함하며 아래 실제로 표시됩니다.

python
name = "Alice"
score = 94.5

print(f"Hello, {name}!")           # "Hello, Alice!"
print(f"Score: {score:.1f}%")      # "Score: 94.5%"
print(f"2 + 2 = {2 + 2}")          # "2 + 2 = 4"
print(f"Name: {name.upper()}")     # "Name: ALICE"

: 뒤의 형식 사양은 값이 표시되는 방식을 제어합니다:

Spec의미
.2f소수점 2자리f"{3.14159:.2f}""3.14"
.0%백분율, 소수점 없음f"{0.94:.0%}""94%"
,천 단위 구분 기호f"{1000000:,}""1,000,000"
>1010자 오른쪽 정렬f"{'hi':>10}"" hi"

대부분 .2f를 사용할 것입니다: 소수를 표시하고 긴 자릿수 실행보다 정돈된 숫자를 원할 때마다. 표의 다른 모든 것은 필요할 때 거기 있습니다. {}에 모든 변수, 산술 또는 메서드 호출을 넣을 수 있습니다.

.2f.0%는 대부분의 디스플레이 서식을 다룹니다. 정렬 지정자 (>, <, ^)는 폭과 결합할 때 표 형식의 출력을 생성합니다. 일반적인 패턴은 {value:[align][width][.precision][type]}입니다. 부분을 인식하면 모든 사양은 모든 조합을 암기하지 않고 읽을 수 있습니다.

같은 사양이 다양한 타입에 다른 것을 의미할 수 있습니다. 각 타입이 자신을 서식화하기 때문입니다: f"{'hi':5}"는 텍스트를 오른쪽에 패딩하는 반면 f"{42:5}"는 왼쪽에 숫자를 패딩합니다. 같은 :5, 반대 결과. 습관으로 삼을 변환 플래그는 !r입니다: repr()을 서식화 전에 실행하므로 문자열을 인용문으로 래핑하고 보이지 않는 문자(탭, 후행 공백, 줄 바꿈)를 보이는 이스케이프 시퀀스로 바꿉니다. 출력이 미묘하게 잘못된 경우 {value}{value!r}로 교환하는 것은 거기 실제로 있는 것을 보는 가장 빠른 방법입니다.

Junof-문자열 열기 따옴표 앞에 f를 넣은 다음 {}에 모든 변수, 합계 또는 메서드 호출을 래핑하고 Python은 선이 실행될 때 결과를 떨어뜨립니다. 중괄호 내의 콜론은 모양을 제어합니다: :.2f 2 소수점은 당신이 기울이는 것입니다. +로 텍스트를 접착하는 것보다 훨씬 더 깔끔합니다.
Junof-문자열f"..."{}에서 모든 표현식을 평가하고 결과를 직접 떨어뜨리며 str()이 필요하지 않습니다. 콜론 뒤에 서식 사양이 있습니다: :.2f, :,, :>10 등등, 모두 {value:[align][width][.precision][type]}를 따릅니다. 부분을 한 번 배우면 모든 사양을 암기하지 않고 읽을 수 있습니다.
Junof-문자열{}은 값의 자체 __format__을 호출하므로 콜론 뒤의 사양은 그 타입이 결정하는 의미이며, 이것이 :5가 텍스트와 숫자를 반대 방향으로 패딩하는 이유입니다. 유지할 플래그는 !r입니다: 입력한 방식으로 값을 보여주므로 여분의 공백과 다른 보이지 않는 쓰레기가 출력이 비정상으로 보이는 순간 튀어 나옵니다.

여러 줄 문자열

한 줄 이상에 걸쳐 있는 문자열을 작성하려면 삼중 따옴표를 사용하세요: 시작에 3개의 "와 끝에 3개. Python은 모든 줄 바꿈과 간격을 입력한 정확히 그대로 유지합니다.

삼중 따옴표 문자열은 모든 공백과 줄 바꿈을 문자 그대로 유지합니다. 이메일 템플릿과 SQL 쿼리와 같은 긴 텍스트 블록의 표준이며 docstring: 함수 또는 클래스 본문의 시작 부분에 배치된 인라인 문서입니다.

삼중 따옴표 문자열은 모든 문자를 정확히 유지합니다. 각 줄의 선행 공간을 포함합니다. 이것이 함정입니다: 코드와 일치하도록 문자를 들여쓰고 그 들여쓰기가 텍스트 내부에 도달합니다. 함수, 클래스 또는 모듈의 본문의 첫 번째 명령문인 경우 Python은 그 객체의 docstring(도움말이 그것을 보여주는 문서)으로 유지하므로 관례는 거기에 짧은 요약을 넣는 것입니다. 들여쓰기를 들어올린 후 지우려면 런타임에 textwrap.dedent()로 제거하세요. 삼중 '''"""는 같이 작동합니다. """가 관례입니다.

python
message = """
Dear Alice,

Thank you for your order.

Best regards,
The Team
"""
Juno여러 줄 문자열 각 끝에 3개의 따옴표를 사용하면 문자열이 여러 줄에 걸쳐 실행될 수 있으며 Python은 입력한 정확히 그대로 모든 줄 바꿈과 공간을 유지합니다. 한 줄에 편하게 맞지 않을 메시지나 템플릿과 같은 텍스트 블록이 있을 때마다 도달하세요.
Juno여러 줄 문자열 삼중 따옴표는 줄 바꿈과 간격을 그대로 유지하므로 이메일 템플릿, SQL 및 모든 긴 블록에 적합합니다. 또한 docstring이 작동하는 방식입니다: 함수나 클래스의 맨 위에 있는 삼중 따옴표 문자열은 그 인라인 문서가 됩니다. 들여쓰기를 조심하세요. 정렬하기 위해 추가한 공간이 텍스트 내부에 끝나기 때문입니다.
Juno여러 줄 문자열 삼중 따옴표 내 모든 것은 문자 그대로 유지되며 선행 공백을 포함합니다. 이것은 함정입니다: 코드와 일치하도록 문자를 들여쓰고 그 들여쓰기가 값에 도달합니다. 함수나 클래스의 맨 위에 짧은 것을 넣으면 도움말이 보여주는 docstring이 됩니다. 소스에서 들여쓰기되도록 필요하지만 값에서 깔끔하려면 textwrap.dedent()를 통해 실행하세요.

이스케이프 시퀀스

일부 문자는 문자열 내에서 직접 입력하기 어렵습니다. Python은 이스케이프 시퀀스를 사용합니다: 뭔가를 나타내는 문자가 뒤따르는 백슬래시. 당신이 지속적으로 사용할 두 가지: 새 줄을 위해 \n, 탭을 위해 \t.

이스케이프 시퀀스는 그렇지 않으면 구문을 중단하거나 직접 입력할 수 없는 문자를 포함시킵니다. 도달할 것들: \n (새 줄), \t (탭), \\ (리터럴 백슬래시), \"\' (일치 구분자 문자열 내 따옴표). Windows 경로는 백슬래시가 필요하며 이스케이프 처리와 충돌합니다. r로 접두사하여 비활성화하세요.

일상적인 \n\t 이상으로 Python은 직접 입력할 수 없는 문자에 대한 유니코드 이스케이프를 지원합니다: \uXXXX\UXXXXXXXX는 문자를 숫자로 이름 지으므로 \N{name}\N{GREEK SMALL LETTER ALPHA}처럼 단어로 이름을 지으므로, 실제 코드에 도달할 것은 원시 문자열이며 r"..."로 작성되므로 이스케이프 처리를 완전히 끕니다. 모든 백슬래시를 변경되지 않은 상태로 전달합니다. Windows 경로와 정규식 패턴에 사용하세요. 백슬래시는 그 소비자가 아닌 Python이 아니라는 의도이며 r을 잊으면 조용하게 잘못된 것과 일치하는 패턴을 생성하는 패턴입니다.

시퀀스문자
\n줄 바꿈
\t
\\리터럴 백슬래시
\"쌍따옴표
\'홑따옴표
python
print("Line one\nLine two")        # 출력 두 줄
print("Name:\tAlice")              # Name:   Alice
path = r"C:\Users\Alice\Documents" # 원시 문자열, 이스케이프 처리 없음
Juno이스케이프 시퀀스 문자열 내의 백슬래시는 "다음 문자를 특별히 읽음"을 의미합니다: \n은 새 줄을 시작하고, \t는 탭을 삽입하고, \\는 한 개의 진짜 백슬래시입니다. 이 두 가지, \n\t는 실제로 입력할 것들입니다. 따옴표 앞에 r을 누르고 백슬래시는 평문으로 돌아갑니다. Windows 경로에 편합니다.
Juno이스케이프 시퀀스\n, \t, \\, 그리고 \"은 일상적인 이스케이프를 다룹니다. 두통을 절약하는 것: 원시 문자열, r"...", 이스케이프 처리를 벗으므로 모든 백슬래시가 문자 그대로 남습니다. Windows 경로와 정규식 패턴에 사용하세요. 백슬래시는 Python 이외의 것을 위합니다.
Juno이스케이프 시퀀스\n\t 과거에는 \N{name} 같은 유니코드 이스케이프가 있지만, 말 일꾼은 원시 문자열 r"..."이므로 모든 백슬래시를 변경되지 않은 상태로 전달합니다. 정규식 패턴과 Windows 경로에 도달하세요. `r`을 잊으면 오류를 알려주기보다 조용하게 잘못된 것과 일치하는 패턴을 제공합니다.

문자열 콘텐츠 확인

Python은 문자열이 포함된 내용에 대해 예/아니오 질문에 답하는 메서드가 있습니다. True 또는 False를 반환합니다. 초기에 가장 유용한 것: isdigit()은 변환하기 전에 문자열이 모두 숫자인지 확인하므로 예상치 못한 입력에 충돌을 피할 수 있습니다.

is* 메서드는 각각 전체 문자열의 특정 성질을 테스트하고 모든 문자가 조건을 만족할 경우만 True를 반환합니다. 그들의 주요 사용은 입력 유효성: 변환 전에 확인하여 예상치 못한 입력에 충돌을 피하세요. isdigit() 이전 int()는 고전적인 패턴이며 Files and exceptions 장에서 다룬 ValueError를 잡는 대안입니다.

이 체크는 평문 ASCII 문자와 숫자만 아닌 모든 유니코드에서 "이 종류의 모든 문자인가"를 묻습니다. 즉, "2".isdigit()은 위첨자 2뿐만 아니라 평범한 "2"True이므로 놀라운 입력이 유효성 체크를 통과하도록 할 수 있습니다. 엄격하게 숫자 0부터 9까지를 의도할 때는 s.isascii() and s.isdigit()을 결합하세요. isnumeric()은 분수와 다른 숫자 값 문자를 세므로 더 광범위입니다. 첫 것처럼 보이는 것이 아니라 실제로 받아들이는 것과 일치하는 가장 좁은 체크에 도달하세요.

python
"42".isdigit()       # True
"hello".isalpha()    # True
"hello42".isalnum()  # True
"   ".isspace()      # True
"Hello".islower()    # False
"HELLO".isupper()    # True
Juno문자열 콘텐츠 확인is* 메서드는 예/아니오 질문에 답하고 모든 문자가 맞을 때만 True를 반환합니다. 처음 사용할 것: 텍스트가 정말 숫자인지 확인하기 위해 int() 전에 isdigit()을 호출하세요. 그래서 이상한 입력은 당신을 충돌하지 않습니다.
Juno문자열 콘텐츠 확인is* 메서드는 전체 문자열이 통과할 때만 `True`이며, 변환하기 전에 입력을 유효성 검사하는 데 편합니다. isdigit() 이전 int()은 고전적인 가드입니다. 빈 문자열이 모든 것에 대해 `False`를 반환하므로 전체 문자열을 테스트한다는 것을 기억하세요.
Juno문자열 콘텐츠 확인 이 체크는 모든 유니코드에 걸쳐 있으므로 평문 ASCII는 아닙니다. 따라서 `isdigit()`은 의도하지 않은 위첨자와 다른 숫자 문자를 통과시킵니다. 숫자 `0`부터 `9`까지를 의도할 때는 쌍으로 사용하세요: `s.isascii() and s.isdigit()`. 처음으로 보이는 가장 좁은 체크가 아닌 실제 입력과 일치하는 가장 좁은 체크를 선택하세요.

실제로

공백을 제거하고 경우를 정규화한 다음 필요한 것을 당겨냅니다. 이 시퀀스는 거의 모든 사용자 제공 텍스트를 처리합니다:

python
raw_input = "  Alice@Example.COM  "
email = raw_input.strip().lower()   # "alice@example.com"

at_pos = email.find("@")
username = email[:at_pos]
domain = email[at_pos + 1:]

print(f"User:   {username}")    # "alice"
print(f"Domain: {domain}")      # "example.com"

부분에서 URL을 작성하고 즉시 유효성 검사 및 파싱:

python
BASE_URL = "https://api.example.com"
version = "v2"
resource = "users"
user_id = 42

url = f"{BASE_URL}/{version}/{resource}/{user_id}"
# "https://api.example.com/v2/users/42"

parts = url.split("://")              # ["https", "api.example.com/v2/users/42"]
protocol = parts[0]                   # "https"
secured = url.startswith("https")
domain = parts[1].split("/")[0]       # "api.example.com"

print(f"Protocol : {protocol}")
print(f"Secure   : {secured}")
print(f"Domain   : {domain}")

find(), 슬라이싱 및 f-문자열 정렬을 사용하여 구조화된 로그 줄 파싱:

python
log_entry = "[2024-01-15 09:42:11] ERROR: File not found: report.csv"

timestamp = log_entry[1:20]
rest = log_entry[22:]                # "ERROR: File not found: report.csv"
colon_pos = rest.find(":")
level = rest[:colon_pos]             # "ERROR"
message = rest[colon_pos + 2:]       # "File not found: report.csv"

print(f"[{timestamp}] {level:>8}: {message}")
# [2024-01-15 09:42:11]    ERROR: File not found: report.csv

find()는 경계를 찾고 슬라이싱은 부분을 추출하고 >8 형식 사양은 심각도 레이블을 오른쪽 정렬하므로 레벨 이름이 길이가 다를 때 열이 일관성 있게 유지됩니다.

메서드 참조

메서드하는 일
.lower() / .upper()모두 소문자 / 모두 대문자로 변환
.title() / .capitalize()각 단어 / 첫 단어만 대문자
.strip() / .lstrip() / .rstrip()주변 공백 제거
.find(sub)첫 일치의 인덱스, 또는 -1
.count(sub)sub이 나타나는 횟수
.startswith(s) / .endswith(s)접두사 / 접미사 확인
.replace(old, new)항목 바꾸기
.split(sep)리스트로 분할
sep.join(iterable)항목을 문자열로 결합
.isdigit() / .isalpha() / .isalnum()문자 타입 체크