125가지 모범 사례로 완성하는 파이썬 코딩의 기술!
125가지 모범 사례로 완성하는 파이썬 코딩의 기술!
AI 코드 시대에도 흔들리지 않는 개발자를 위한 파이썬 설계의 기준!
2015년 1판이 출간된 이후 파이썬 프로그래밍 분야에서 독보적인 존재감을 지켜 온 『이펙티브 파이썬』은 파이썬을 ‘쓸 줄 아는 코드’에서 ‘설계할 줄 아는 코드’로 끌어올리고, 개발자의 역량을 한 단계 확장시키는 실전 지침서다. 실무에서 마주치는 핵심 주제를 함수와 제너레이터, 클래스 설계부터 동시성, 성능 최적화, 테스트까지 총 125개의 구체적이고 실용적인 아이템으로 정리했다. 각 아이템에서는 왜 그 방식이 더 나은지를 명쾌한 논리와 사례로 설명하고, 가독성 · 유지보수성 · 안정성 · 성능을 모두 고려한 설계 원칙을 제시했다. 3판에서는 파이썬 3.13까지의 최신 버전을 기준으로 내용을 전면 개정하고, 새로운 아이템 35개를 추가해 최신 사례를 충실히 반영했으며, 기존 조언 또한 변화해 온 모범 사례를 반영해 대폭 수정했다. 이 책은 AI가 코드를 만드는 현시대에 더 나은 선택을 할 수 있도록 개발자의 역량과 판단 기준을 높여 줄 것이다.
1장 파이썬답게 생각하기
[아이템 1] 사용 중인 파이썬의 버전을 알아두라
[아이템 2] PEP 8 스타일 가이드를 따르라
________공백
________명명 규약
________표현식과 문장
________임포트
________자동화
[아이템 3] 파이썬이 컴파일 시점에 오류를 감지하리라고 절대로 기대하지 말라
[아이템 4] 복잡한 식을 쓰는 대신 도우미 함수를 작성하라
[아이템 5] 인덱스를 사용하는 대신 다중 대입을 사용해 데이터를 언패킹하라
[아이템 6] 원소가 하나뿐인 튜플은 항상 괄호로 둘러싸라
[아이템 7] 단순한 인라인 로직의 경우 조건식 사용을 검토하라
[아이템 8] 대입식을 사용해 반복을 피하라
[아이템 9] 흐름 제어 시 구조분해에 match를 사용할 것을 고려하라. 하지만 if 문으로 충분하다면 match를 피하라
________match는 구조분해를 한다
________반쯤 구조화된 데이터와 캡슐화된 데이터
2장 문자열과 슬라이스
[아이템 10] bytes와 str의 차이를 이해하라
[아이템 11] C 스타일 형식 문자열과 str.format보다는 t-문자열이나 f-문자열 인터폴레이션을 사용하라
_________C 스타일 형식화
_________내장 함수 format과 str.format
_________인터폴레이션 형식 문자열
[아이템 12] 객체를 출력할 때는 repr과 str의 차이를 이해하라
[아이템 13] 암시적 문자열 연결보다는 명시적 연결을 선호하라. 특히 리스트의 경우 명시적 연결을 사용하라
[아이템 14] 시퀀스를 슬라이스하는 방법을 익혀라
[아이템 15] 스트라이드와 슬라이스를 한 식에 함께 사용하지 말라
[아이템 16] 슬라이스 대신 포괄적 언패킹을 선호하라
3장 루프와 이터레이션
[아이템 17] range보다는 enumerate를 사용하라
[아이템 18] 여러 이터레이터에 대해 나란히 루프를 수행하려면 zip을 사용하라
[아이템 19] for나 while 루프 뒤에 else 블록을 사용하지 말라
[아이템 20] 루프 종료 후 for 루프 변수를 사용하지 말라
[아이템 21] 인자에 대해 이터레이션할 때는 방어적으로 접근하라
[아이템 22] 컨테이너에 대해 이터레이션하는 중이라면 결코 컨테이너의 내용을 변경하지 말라. 변경을 해야 한다면 컨테이너를 직접 이터레이션하지 말고 복사본이나 캐시를 사용하라
[아이템 23] 효율적인 쇼트 서킷 로직을 사용하려면 any나 all에게 이터레이터를 전달하라
[아이템 24] 이터레이터나 제너레이터를 다룰 때는 itertools를 사용하라
_________여러 이터레이터 연결하기
이터레이터에서 원소 거르기
이터레이터에서 원소의 조합 만들어내기
4장 딕셔너리
[아이템 25] 딕셔너리 삽입 순서에 의존할 때는 조심하라
[아이템 26] in을 쓰고 딕셔너리 키가 없는 경우를 KeyError로 처리하지 말고 get을 사용하라
[아이템 27] 내부 상태에서 원소가 없는 경우를 처리할 때는 setdefault보다 defaultdict를 사용하라
[아이템 28] __missing__을 사용해 키에 따라 다른 디폴트 값을 생성하는 방법을 알아두라
[아이템 29] 딕셔너리, 리스트, 튜플을 깊게 중첩시키기보다는 클래스를 합성하라
클래스를 활용해 리팩터링하기
5장 함수
[아이템 30] 함수 인자가 변경될 수 있다는 점을 기억하라
[아이템 31] 세 개를 초과하는 변수를 언패킹하게 만들지 말고 전용 결과 객체를 반환하라
[아이템 32] None을 반환하기보다는 예외를 발생시켜라
[아이템 33] 클로저가 변수 영역 및 nonlocal과 상호작용하는 방식을 이해하라
[아이템 34] 변수 위치 인자를 사용해 시각적인 잡음을 줄여라
[아이템 35] 키워드 인자로 선택적인 기능을 제공하라
[아이템 36] None과 독스트링을 사용하여 동적인 디폴트 인자를 지정하라
[아이템 37] 위치로만 인자를 지정하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라
[아이템 38] functools.wraps를 사용해 함수 데코레이터를 정의하라
[아이템 39] 글루 함수로는 lambda 식보다 functools.partial을 사용하라
6장 컴프리헨션과 제너레이터
[아이템 40] map과 filter 대신 컴프리헨션을 사용하라
[아이템 41] 컴프리헨션 내부에 제어 하위 식을 3개 이상 사용하지 말라
[아이템 42] 대입식을 사용해 컴프리헨션 안에서 반복 작업을 피하라
[아이템 43] 리스트를 반환하기보다는 제너레이터를 사용하라
[아이템 44] 긴 리스트 컴프리헨션보다는 제너레이터 식을 사용하라
[아이템 45] yield from을 사용해 여러 제너레이터를 합성하라
[아이템 46] 제너레이터의 send 메서드를 호출하는 대신 이터레이터를 제너레이터에게 인자로 전달하라
[아이템 47] 제너레이터에서 throw 메서드를 쓰는 대신 클래스로 이터레이션의 상태 전이를 관리하라
7장 클래스와 인터페이스
[아이템 48] 간단한 인터페이스의 경우 클래스 대신 함수를 받아라
[아이템 49] 함수와 isinstance 검사를 사용하기보다 객체지향 다형성을 선호하라
[아이템 50] 객체지향 다형성 대신 함수형 스타일 프로그래밍을 할 때는 functools.singledispatch를 고려하라
[아이템 51] 경량 클래스를 정의할 때는 dataclasses를 선호하라
_________ __init__ 보일러플레이트 피하기
_________초기화 인자를 키워드 인자로 받도록 하라
_________디폴트 애트리뷰트 값 지정하기
_________객체를 문자열로 표현하기
_________객체를 튜플로 변환하기
_________객체를 딕셔너리로 변환하기
_________객체가 동등한지 확인하기
_________객체를 서로 비교할 수 있게 하기
[아이템 52] 객체를 제너릭하게 구성하려면 @classmethod를 통한 다형성을 활용하라
[아이템 53] super로 부모 클래스를 초기화하라
[아이템 54] 기능을 합성할 때는 믹스인 클래스를 사용하라
[아이템 55] 비공개 애트리뷰트보다는 공개 애트리뷰트를 사용하라
[아이템 56] 불변 객체를 생성할 때는 dataclasses를 선호하라
_________객체의 변경 막기
_________애트리뷰트를 변경한 객체 복사본 생성하기
_________딕셔너리와 집합에서 불변 객체 사용하기
[아이템 57] 커스텀 컨테이너 타입을 정의할 때는 collections.abc를 상속하라
8장 메타클래스와 애트리뷰트
[아이템 58] 세터와 게터 메서드 대신 평범한 애트리뷰트를 사용하라
[아이템 59] 애트리뷰트를 리팩터링하는 대신 @property를 사용하라
[아이템 60] 재사용 가능한 @property 메서드를 만들려면 디스크립터를 사용하라
[아이템 61] 지연 계산 애트리뷰트가 필요하면 __getattr__, __getattribute__, __setattr__를 사용하라
[아이템 62] __init_subclass__를 사용해 하위 클래스를 검증하라
[아이템 63] __init_subclass__를 사용해 클래스 확장을 등록하라
[아이템 64] __set_name__으로 클래스 애트리뷰트를 표시하라
[아이템 65] 클래스 본문 정의 순서를 고려해 애트리뷰트 간 관계를 설정하라
[아이템 66] 합성 가능한 클래스 확장이 필요하면 메타클래스보다는 클래스 데코레이터를 사용하라
9장 동시성과 병렬성
[아이템 67] 자식 프로세스를 관리하기 위해 subprocess를 사용하라
[아이템 68] 스레드를 블러킹 I/O에 사용하고 병렬성에는 사용하지 말라
[아이템 69] 스레드에서 데이터 경합을 피하기 위해 Lock을 사용하라
[아이템 70] Queue를 사용해 스레드 사이의 작업을 조율하라
_________대안: Queue
[아이템 71] 언제 동시성이 필요할지 인식하는 방법을 알아두라
[아이템 72] 온디멘드로 팬아웃을 진행하려면 새로운 스레드 생성을 피하라
[아이템 73] 동시성과 Queue를 사용하기 위해 코드를 어떻게 리팩터링해야 하는지 이해하라
[아이템 74] 동시성을 위해 스레드가 필요한 경우에는 ThreadPoolExecutor를 사용하라
[아이템 75] 코루틴을 사용해 높은 I/O 동시성을 달성하라
[아이템 76] 스레드를 사용한 I/O를 어떻게 asyncio로 포팅할 수 있는지 알아두라
[아이템 77] asyncio로 쉽게 옮겨갈 수 있도록 스레드와 코루틴을 함께 사용하라
_________하향식 접근 방법
_________상향식 접근 방법
[아이템 78] async에 친화적인 작업자 스레드를 사용해서 asyncio 이벤트 루프의 응답성을 최대화하라
[아이템 79] 진정한 병렬성을 살리려면 concurrent.futures를 사용하라
10장 강건성
[아이템 80] try/except/else/finally의 각 블록을 잘 활용하라
_________finally 블록
_________else 블록
_________모든 요소를 한꺼번에 사용하기
[아이템 81] assert로 내부 가정을 검증하고 예상을 벗어난 경우 예외를 raise하라
[아이템 82] 재사용 가능한 try/finally 동작을 원한다면 contextlib과 with 문을 사용하라
_________as 타깃 지정 활성화하기
[아이템 83] 언제나 try 블록을 최대한 짧게 만들라
[아이템 84] 예외 변수가 사라지는 것에 주의하라
[아이템 85] Exception 클래스를 catch할 때는 조심하라
[아이템 86] Exception과 BaseException의 차이를 이해하라
[아이템 87] traceback을 사용해 예외 보고를 개선하라
[아이템 88] traceback을 명확히 하기 위해 예외를 명시적으로 연결할 것을 고려하라
[아이템 89] 항상 자원을 제너레이터에게 넘기고 호출하는 쪽이 제너레이터 밖에서 자원을 해제하게 하라
[아이템 90] 절대로 __debug__를 False로 설정하지 말라
[아이템 91] 개발자 도구를 만드는 경우가 아니라면 exec와 eval을 피하라
11장 성능
[아이템 92] 최적화하기 전에 프로파일링을 하라
[아이템 93] timeit을 사용한 마이크로벤치마크를 통해 성능이 중요한 코드를 최적화하라
[아이템 94] 언제, 왜 파이썬을 다른 프로그래밍 언어로 대체할지 알아두라
[아이템 95] 네이티브 라이브러리와 빠르게 통합하기 위해 ctypes를 고려하라
[아이템 96] 성능과 편의성을 최대화하기 위해 확장 모듈을 고려하라
[아이템 97] 프로그램 시작 시간을 줄이기 위해 미리 컴파일된 바이트코드와 파일 시스템 캐시에 의존하라
[아이템 98] 지연 로딩 모듈과 동적 임포트를 사용해 프로그램 시작 시간을 줄여라
[아이템 99] bytes를 복사하지 않고 다루려면 memoryview와 bytearray를 사용하라
12장 데이터 구조와 알고리즘
[아이템 100] 복잡한 기준을 사용해 정렬할 때는 key 파라미터를 사용하라
[아이템 101] sort와 sorted의 차이를 이해하라
[아이템 102] 정렬된 시퀀스를 검색할 때는 bisect를 사용하라
[아이템 103] 생산자-소비자 큐로 deque를 사용하라
[아이템 104] 우선순위 큐로 heapq를 사용하는 방법을 알아두라
[아이템 105] 지역 시간에는 time보다는 datetime을 사용하라
__________time 모듈
__________datetime 모듈
[아이템 106] 정확도가 매우 중요한 경우에는 decimal을 사용하라
[아이템 107] copyreg를 사용해 pickle을 더 신뢰성 있게 만들라
__________디폴트 애트리뷰트 값
__________클래스 버전 지정
__________안정적인 임포트 경로
13장 테스트와 디버깅
[아이템 108] TestCase 하위 클래스를 사용해 프로그램에서 연관된 행동 방식을 검증하라
[아이템 109] 단위 테스트보다 통합 테스트를 선호하라
[아이템 110] setUp, tearDown, setUpModule, tearDownModule을 사용해 각각의 테스트를 격리하라
[아이템 111] 목을 사용해 의존성이 복잡한 코드를 테스트하라
[아이템 112] 의존성을 캡슐화해서 모킹과 테스트를 쉽게 만들라
[아이템 113] assertAlmostEqual을 써서 부동소수점 테스트의 정밀도를 제어하라
[아이템 114] pdb를 사용한 대화형 디버깅을 고려하라
[아이템 115] 프로그램이 메모리를 사용하는 방식과 메모리 누수를 이해하기 위해 tracemalloc을 사용하라
14장 협업
[아이템 116] 커뮤니티에서 만든 모듈을 어디서 찾을 수 있는지 알아두라
[아이템 117] 가상 환경을 사용해 의존성을 격리하고 반복 생성할 수 있게 하라
__________명령줄에서 venv 사용하기
__________의존성 재생성하기
[아이템 118] 모든 함수, 클래스, 모듈에 독스트링을 작성하라
__________모듈 문서화하기
__________클래스 문서화하기
__________함수 문서화하기
__________독스트링과 타입 애너테이션 사용하기
[아이템 119] 패키지를 사용해 모듈을 체계화하고 안정적인 API를 제공하라
__________네임 스페이스
__________안정적인 API
[아이템 120] 배포 환경을 설정하기 위해 모듈 영역의 코드 사용을 고려하라
[아이템 121] 호출자를 API로부터 보호하기 위해 최상위 Exception을 정의하라
[아이템 122] 순환 의존성을 깨는 방법을 알아두라
__________임포트 순서 바꾸기
__________임포트, 설정, 실행
[아이템 123] 리팩터링과 마이그레이션 방법을 알려주기 위해 warnings를 사용하라
[아이템 124] typing을 통한 정적 분석으로 버그를 없애라
[아이템 125] 파이썬 번들을 만들 때는 zipimport나 zipapp보다는 오픈 소스 프로젝트를 선호하라
필요한 자료를 선택하세요.
독자의견 남기기