2.11. 조건문

조건문(conditional) 은 어떤 검사가 참으로 평가될 때만 코드 블록을 실행합니다. 키워드는 if 이며, 선택적으로 하나 이상의 elif (“else if”) 분기와 마지막 else 가 뒤따를 수 있습니다.

n = 42

if n > 0:
    print("positive")
elif n < 0:
    print("negative")
else:
    print("zero")

각 분기의 본문은 그 아래에 들여쓰기된 모든 것입니다(관례상 공백 네 칸). Python은 분기를 순서대로 훑어 검사가 참인 첫 번째 것을 실행하고 나머지는 건너뜁니다. else 블록은 앞선 모든 검사가 거짓일 때만 실행되며, 항상 선택 사항입니다.

if/elif/else 를 보여주는 흐름도: 두 개의 마름모꼴 결정 검사와 그 본문이 있고, 두 검사가 모두 거짓이면 마지막 else 본문으로 떨어집니다.

오직 하나의 분기만 실행됩니다. 검사는 위에서 아래로 평가되어 하나가 성공할 때까지 진행되고, 나머지는 건너뜁니다.

2.11.1. 참 같음(Truthiness)

if 안의 검사가 반드시 TrueFalse 를 반환할 필요는 없습니다. 어떤 값이든 참 같음(truthy) 또는 거짓 같음(falsy) 으로 간주됩니다. 거짓 같은 값은 다음과 같습니다:

  • FalseNone

  • 숫자 0: 0, 0.0

  • 빈 시퀀스와 컬렉션: "", [], (), {}, b""

그 밖의 모든 것은 참 같습니다. 이를 통해 간결한 검사를 작성할 수 있습니다:

if name:                     # false on empty string
    print("hello", name)

if items:                    # false on empty list, dict, etc.
    process(items)

참 같음이 의미를 바꾼다는 점을 유의하세요. if value:if value is not None:같지 않습니다. 전자는 value0 이나 "" 일 때도 거짓이기 때문입니다. 정말로 “이것이 정확히 None 인가” 를 뜻한다면 is None / is not None 을 명시적으로 사용하세요.

2.11.2. 삼항 표현식

조건문은 표현식 안에 나타날 수 있습니다:

label = "even" if n % 2 == 0 else "odd"

n % 2 == 0 이면 label"even" 이고 그렇지 않으면 "odd"“ 로 읽습니다. 한 줄짜리에 편리하지만, 한 줄을 넘는 것이라면 완전한 if 문이 읽기 더 쉽습니다.

2.11.3. 중첩과 조기 반환

조건문은 임의로 깊게 중첩할 수 있지만, 들여쓰기 계층이 하나씩 늘어날 때마다 함수는 읽기 어려워집니다. 아래 예제는 실제 작업을 하기 전에 네 가지 조건을 검사하고, 유용한 줄을 네 칸 들여쓰기 안에 묻어 둡니다:

def process(item):
    if item is not None:
        if item.is_valid():
            if item.size() > 0:
                if item.owner == "me":
                    return do_the_work(item)
    return None

두 가지 패턴이 이런 종류의 코드를 평평하게 만듭니다.

2.11.3.1. 가드를 위한 조기 반환

모든 “빠져나가는” 경우를 각각 자체 return 과 함께 먼저 처리하여, 주요 로직이 바깥쪽 들여쓰기에 머물도록 합니다. 각 가드는 “이것은 우리가 처리하는 경우가 아니다; 떠나라” 로 읽힙니다:

def process(item):
    if item is None:
        return None
    if not item.is_valid():
        return None
    if item.size() == 0:
        return None
    if item.owner != "me":
        return None
    return do_the_work(item)

이제 “주요 경로” 는 네 겹 안에 묻히지 않고 함수 맨 아래에 한 줄로 있습니다. 이 방식은 때때로 가드 절(guard clause) 패턴이라 불립니다.

2.11.3.2. and / or 로 검사 결합하기

같은 분기에 대해 여러 조건이 모두 성립해야 할 때는 중첩하는 대신 and 로 결합하세요. 각각 독립적으로 그 분기를 촉발하는 조건은 or 로 결합합니다:

# all must hold -- use `and`
if user.is_admin() and user.has_permission("write") and not locked:
    save()

# any one of them is enough -- use `or`
if c == " " or c == "\t" or c == "\n":
    whitespace_count += 1

두 형태 모두 단락 평가(short-circuit)를 하므로, 오른쪽의 비싼 검사는 왼쪽의 더 저렴한 검사가 아직 문제를 결론짓지 못했을 때만 실행됩니다.