Chaper 1: Pythonic Thinking
The best way to do the most common things in Python
Item 1: Know Which Version of Python You’re Using
--version flag를 사용하여 사용중인 파이썬 버전 확인
python --version
또한 시스템 내장 모듈의 값을 검사함으로써 런타임에 사용 중인 파이썬 버전을 파악할 수 있다.
import sys
print(sys.version_info)
print(sys.version)
Item 2: Follow the PEP 8 Style Guide
Python Enhancement Proposal #8(PEP 8)
Whitespace
Naming
Expressions and Statements
- []나 ''등 비어있는 목록은 암묵적으로 False로 평가
- 비어있지 않은 목록([1], 'hi' 등)은 True
- if, for, while문 등의 복합문을 single-line으로 작성하는 것을 지양
- 식을 한 줄에 작성할 수 없는 경우 괄호로 묶고, 줄바꿈 및 들여쓰기 추가
Imports
- import문은 항상 파일 맨 위에 작성
- 모듈을 가져올 때 절대경로 사용
- 표준 라이브러리 모듈, third-party module, 사용자 고유 모듈 순으로 가져오기
Item 3: Kniw the Differences Between bytes and str
파이썬에서 character를 나타내는 두가지 유형
1. byte
2. str
- byte는 8bit 값의 시퀀스를 포함하고 str은 Unicode code points의 시퀀스를 포함한다.
- helper function을 사용하여 입력이 예상되는 문자 시퀀스 유형을 확인할 수 있다.
- byte instance와 str instance를 +, >, ==, % 등의 연산자로 함께 사용할 수 없다.
- 파일에서 이진 데이터를 읽거나 쓸 때는 'rb' 또는 'wb'를 사용하여 파일을 open한다.
- 파일에서 유니코드 데이터를 읽거나 쓸 때 시스템의 기본 텍스트 인코딩에 주의해야한다. 예상치 못한 상황을 방지하려면 다음과 같이 인코딩 매개 변수를 명시적으로 전달하여 open한다.
with open('data.bin', 'r', encoding='cp1252') as f:
data = f.read()
C-style 형식 문자열 및 str. 형식보다 F-String 선호
python 문자열 formatting 방식
1. % 연산자 사용
- %s, %x, %f 등의 형식 지정자로 사용할 수 있지만, % 연산자를 사용하는 C-style 형식 문자열은 gotchas 및 verbosity 등 다양한 문제로 어려움을 겪는다.
- str.format
key = 'my_var'
value = 1.234
formatted = '{} = {:.2f}'.format(key, value)
print(formatted)
- {}내에 전달된 인수의 위치 index를 지정하여 자리를 바꿀 수 있다.
formatted = '{1} = {0}'.format(key, value)
print(formatted)
- 같은 위치의 index를 여러번 사용할 수 있다.
- Interpolated Format Strings
- C-style 형식 문자열의 가장 큰 문자를 해결
- 형식 문자열에 f문자를 접두사로 붙인 구문을 사용(f-string)
- {}안에 전체 파이썬 표현식을 넣을 수 있다. => 형식 지정자에 임의의 Python 표현식을 직접 포함할 수 있기 때문에 간결하지만 강력하다.
f_string = f'#{i+1}: {item.title():<10s} = {round(count)}'
- f-string 문자열을 여러 줄로 분할할 수 있다.
Item 5: Write Helper Functions Instead of Complex Expressions
- 파이썬은 지나치게 복잡하고 읽기 어려운 표현을 한 줄로 쉽게 작성할 수 있다.
- 동일한 논리를 반복적으로 사용해야 하는 경우 helper function을 사용할 수 있다.
- if/else 표현식은 bool 연산자, or, and를 사용하는 것보다 읽기 쉬운 대안을 제공한다.
Item 6: Prefer Multiple Assignment Unpacking Over Indexing
- tuple
- 파이썬에는 순서대로 배열된 값을 만들고 변경할 수 없는 tuple type이 있다.
- 튜플이 생성되면 인덱스에 새 값을 할당하여 수정할 수 없다.
- unpacking
- 단일 문에 여러 값을 할당할 수 있다.
- 반복 가능한 항목 내에서 목록, 시퀀스 및 여러 수준의 임의 반복 가능 항목에 할당할 때 작동한다.
- 임시 변수를 만들 필요 없이 unpacking하여 값을 제자리에서 교환할 수 있다.
# 오름차순 정렬
def bubble_sort(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i] < a[i-1]:
a[i-1], a[i] = a[i], a[i-1] # Swap
names = ['pretzels', 'carrots', 'arugula', 'bacon']
bubble_sort(names)
print(names)
.
- 짧고 이해하기 쉽다.(index를 사용하여 접근할 필요X)
snacks = [('bacon', 350), ('donut', 240), ('muffin', 190)]
for rank, (name, calories) in enumerate(snacks, 1):
print(f'#{rank}: {name} has {calories} calories')
Item 7: Prefer enumerate Over range
range
- 정수 집합에서 반복되는 loop에 유용
- 문자열 목록과 같이 반복할 데이터 구조가 있는 경우에도 사용 가능하다.
- 그러나, 그 목록의 길이를 알아야 하고 배열에 index를 붙이는 단계를 거치면 읽기 어려워진다.
enumerate
- iterator 위에 루프를 만들고 iterator에서 각 항목의 index를 가져올 수 있는 간결한 구문을 제공
- 열거할 두 번째 매개 변수를 제공하여 카운트를 시작할 숫자를 지정할 수 있다(기본값은 0).
- 아래의 코드에서 i는 1부터 count 시작
for i, flavor in enumerate(flavor_list, 1):
print(f'{i}: {flavor}')
Item 8: Use zip to Process Iterators in Parallel
zip
- zip 기능을 사용하여 여러 iterator들을 병렬로 반복할 수 있다.
- zip은 tuple을 생성하는 generator를 만들어 무한히 긴 입력에 사용할 수 있다.
- 길이가 동일하지 않은 iterator를 잘라내지 않고 사용하려면 iter
tools 모듈의 zip_longest 함수를 사용한다.
import itertools
names = ['Cecilia', 'Lise', 'Marie']
counts = [len(n) for n in names]
for name, count in itertools.zip_longest(names, counts):
print(f'{name}: {count}')
Item 9: Avoid else Blocks After for and while Loops
- 파이썬은 내부 블록을 루프하는 동안 else 블록을 즉시 따라갈 수 있는 특별한 구문을 가지고 있다.
- 루프 뒤의 else 블록은 루프 본문에 break 문이 없는 경우에만 실행된다.
- 루프 뒤에 else 블록을 사용하는 것은 직관적이지 않고 혼란스러울 수 있으므로 사용하지 않는 것이 좋다.
Item 10: Prevent Repetition with Assignment Expressions
- 일반적으로 그룹 내에서 동일한 표현식이나 할당을 여러 번 반복하는 경우 가독성을 향상시키기 위해 할당 표현식을 사용하는 것을 고려할 수 있다.
- 할당 표현식은 walrus 연산자(:=)를 사용하여 단일 표현식에서 변수 이름을 할당하고 평가하므로 반복이 줄어든다.
- 할당 표현식이 더 큰 표현식의 하위 표현식인 경우 괄호로 둘러싸야 한다.
- switch/case와 do/while문은 파이썬에서 사용할 수 없지만, 할당 표현식을 사용하여 훨씬 더 명확하게 표현할 수 있다.