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 블록은 앞선 모든 검사가 거짓일 때만 실행되며, 항상 선택 사항입니다.
오직 하나의 분기만 실행됩니다. 검사는 위에서 아래로 평가되어 하나가 성공할 때까지 진행되고, 나머지는 건너뜁니다.¶
2.11.1. 참 같음(Truthiness)¶
if 안의 검사가 반드시 True 나 False 를 반환할 필요는 없습니다. 어떤 값이든 참 같음(truthy) 또는 거짓 같음(falsy) 으로 간주됩니다. 거짓 같은 값은 다음과 같습니다:
그 밖의 모든 것은 참 같습니다. 이를 통해 간결한 검사를 작성할 수 있습니다:
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: 과 같지 않습니다. 전자는 value 가 0 이나 "" 일 때도 거짓이기 때문입니다. 정말로 “이것이 정확히 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)를 하므로, 오른쪽의 비싼 검사는 왼쪽의 더 저렴한 검사가 아직 문제를 결론짓지 못했을 때만 실행됩니다.