PEP 20–The Zen of Python

파이썬의 철학과 디자인 원칙을 담고 있다.
파이썬 인터프리터에서 import this를 실행하면 볼 수 있다.

1. Beautiful is Better than Ugly. (아름다움이 추한 것보다 낫다)

코드는 보기 좋고 이해하기 쉽게 작성해야 한다.

1
2
3
4
5
6
7
8
# 아름다운 코드
names = ['Alice', 'Bob', 'Charlie']
for name in names:
    print(f"Hello, {name}!")

# 추한 코드
x=['Alice','Bob','Charlie']
for i in range(len(x)):print("Hello, "+x[i]+"!")

2. Explicit is Better than Implicit. (명시적이 암시적인 것보다 낫다)

코드의 의도를 명확히 표현해야 한다.

1
2
3
4
5
6
7
# 명시적
def calculate_area(width, height):
    return width * height

# 암시적
def calc(x, y):
    return x * y

3. Simple is Better than Complex. (단순함이 복잡한 것보다 낫다)

가능한 한 간단한 해결책을 선택해야 한다.

1
2
3
4
5
6
7
8
# 단순
numbers = [1, 2, 3, 4, 5]
squared = [n**2 for n in numbers]

# 복잡
squared = []
for i in range(len(numbers)):
    squared.append(numbers[i]**2)

4. Complex is Better than Complicated. (복잡함이 난해한 것보다 낫다)

필요한 복잡성은 허용하되, 불필요하게 어렵게 만들지 않아야 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 복잡하지만 이해 가능
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

# 난해한 코드
def qs(a):return a if len(a)<=1 else qs([x for x in a[1:]if x<a[0]])+[a[0]]+qs([x for x in a[1:]if x>=a[0]])

5. Flat is Better than Nested. (평평한 것이 중첩된 것보다 낫다)

깊은 중첩을 피하고 코드를 평평하게 유지해야 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 평평한 구조
def process_data(data):
    if not data:
        return None
    if data['status'] != 'active':
        return None
    return data['value']

# 중첩된 구조
def process_data(data):
    if data:
        if data['status'] == 'active':
            return data['value']
return None

6. Sparse is Better than Dense. (여유로운 것이 밀집된 것보다 낫다)

코드는 읽기 쉽도록 적절히 공간을 두어야 합니다.

1
2
3
4
5
6
7
# 여유로운 코드
def greet(name):
    message = f"Hello, {name}!"
    print(message)

# 밀집된 코드
def greet(name):print(f"Hello, {name}!")

7. Readability Counts. (가독성이 중요하다)

코드는 다른 사람이 쉽게 읽고 이해할 수 있어야 합니다.

1
2
3
4
5
6
7
8
9
# 가독성 좋은 코드
def calculate_average(numbers):
    total = sum(numbers)
    count = len(numbers)
    return total / count if count > 0 else 0

# 가독성 나쁜 코드
def calc_avg(n):
    return sum(n)/len(n) if n else 0

8. Special Cases Aren’t Special Enough to Break the Rules. (특별한 경우도 규칙을 어길 정도로 특별하지 않다)

일관성을 유지하는 것이 중요하며, 특별한 경우라도 규칙을 지켜야 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 규칙을 지키는 코드
def process_all_items(items):
    for item in items:
        process_item(item)

# 규칙을 어기는 코드
def process_all_items(items):
    process_item(items[0])  # 첫 번째 항목만 특별 처리
    for item in items[1:]:
        process_item(item)

9. Although Practicality Beats Purity. (실용성은 순수성에 우선한다)

때로는 실용적인 해결책이 이론적으로 완벽한 해결책보다 낫습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 순수하지만 비실용적인 코드
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# 실용적인 코드
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

10. Errors Should Never Pass Silently. (오류는 조용히 넘어가지 말아야 한다)

오류가 발생하면 명확하게 처리해야 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 오류를 명확히 처리하는 코드
def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

# 오류를 무시하는 코드
def divide(a, b):
    try:
        return a / b
    except:
        pass

11. Unless Explicitly Silenced. (명시적으로 억제하지 않는 한)

의도적으로 오류를 무시할 때는 그 이유를 명확히 해야 합니다.

1
2
3
4
5
6
7
# 명시적으로 오류를 무시하는 코드
def try_operation():
    try:
        perform_operation()
    except SpecificError:
        # 이 특정 오류는 무시해도 됨
        pass

12. In the Face of Ambiguity, Refuse the Temptation to Guess. (모호함에 직면했을 때, 추측하려는 유혹을 거부하라)

코드의 의도가 불분명할 때는 명확히 해야 합니다.

1
2
3
4
5
6
7
# 모호한 코드
def process(x):
    return x * 2  # x가 무엇인지 불분명

# 명확한 코드
def double_number(number: int) -> int:
    return number * 2

13. There Should Be One– and Preferably only One –obvious way to Do It. (문제를 해결하는 명확한 방법은 하나여야 한다)

같은 작업을 수행하는 여러 방법이 있으면 혼란스러울 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 하나의 명확한 방법
names = ['Alice', 'Bob', 'Charlie']
for name in names:
    print(name)

# 여러 가지 방법 (혼란스러움)
for i in range(len(names)):
    print(names[i])

[print(name) for name in names]

14. Although that way May not Be Obvious at First unless You’re Dutch. (네덜란드 사람이 아니라면 처음에는 명확하지 않을 수 있다)

최선의 해결책이 처음에는 명확하지 않을 수 있습니다. (Python의 창시자 Guido van Rossum이 네덜란드 사람이라는 농담)
이 원칙은 특정 코드 예시보다는 Python 언어 설계 철학을 반영합니다.

15. Now is Better than Never. (지금 하는 것이 안 하는 것보다 낫다)

완벽을 추구하다가 아무것도 하지 않는 것보다는 현재 할 수 있는 것을 하는 것이 좋습니다.

1
2
3
4
5
6
7
8
# 지금 구현하는 코드
def simple_function():
    # TODO: 나중에 개선하기
    return "Hello, World!"

# 구현을 미루는 경우
def complex_function():
    pass  # 나중에 구현하겠다고 생각만 하는 경우

16. Although Never is Often Better than Right Now. (아예 안 하는 것이 지금 당장 하는 것보다 나을 때도 있다)

충분한 고려 없이 성급하게 구현하는 것보다는 때로는 구현을 미루는 것이 좋을 수 있습니다.

1
2
3
4
5
6
7
# 성급한 구현
def rushed_feature():
    # 충분히 고려하지 않은 채 구현한 코드
    return "Incomplete feature"

# 신중한 접근
# TODO: 요구사항을 더 잘 이해한 후에 구현하기

17. If the Implementation is Hard to Explain, It’s a Bad Idea. (구현을 설명하기 어렵다면, 좋은 아이디어가 아니다)

코드가 복잡해서 설명하기 어렵다면, 더 간단한 방법을 찾아야 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 설명하기 어려운 구현
def complex_algorithm(data):
    return [x for x in set([y for y in data if y > sum(data) / len(data)]) if x % 2 == 0]

# 설명하기 쉬운 구현
def simple_algorithm(data):
    average = sum(data) / len(data)
    above_average = [x for x in data if x > average]
    unique_values = set(above_average)
    return [x for x in unique_values if x % 2 == 0]

18. If the Implementation is Easy to Explain, it May Be a Good Idea. (구현을 설명하기 쉽다면, 좋은 아이디어일 수 있다)

간단하고 명확한 코드는 대개 좋은 설계의 결과입니다.

1
2
3
4
5
6
7
8
# 설명하기 쉬운 구현
def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

19. Namespaces Are One Honking Great Idea – Let’s Do More of Those! (네임스페이스는 정말 훌륭한 아이디어다 – 더 많이 사용하자!)

네임스페이스를 사용하면 코드를 더 잘 구조화하고 이름 충돌을 피할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 네임스페이스 사용
import math

def calculate_area(radius):
    return math.pi * radius**2

# 네임스페이스 없이 사용
from math import *

def calculate_area(radius):
    return pi * radius**2  # pi가 어디서 왔는지 불분명

참고 및 출처