Chapter1. 인터프리터
•
파이썬은 인터프리터 언어입니다. 컴파일과 링크 단계가 필요 없으므로 개발 시간을 상당히 단축해줍니다.
•
파이썬 설치 후 CLI에서 python3.11 을 통해 인터프리터 접근
EOF(end-of-file) 문자인 Control + D 또는 quit() 커맨드를 통해 종료
•
대화형 모드에서는 기본 프롬프트 >>> 와 보조 프롬프트 … 사용 (Shift + Enter로 멀티라인 작성)
•
파이썬에서의 주석은 # (주석은 첫 줄, 공백이나 코드 뒤에 가능하고 문자열에선 문자로 인식함)
•
기본적으로, 파이썬 소스 파일들은 UTF-8으로 인코드 된 것으로 취급됩니다.
하지만 표준 라이브러리는 오직 ASCII 문자만 식별자로 사용하고 있는데, 범용 코드에서는 이 관례를 따르는 것이 좋습니다.
#!/usr/bin/env python3
# -*- coding: encoding -*-
JSON
복사
인코딩을 기본값 외의 것으로 선언하려면, 파일의 첫 줄에 특별한 형태의 주석 문을 추가해야 합니다.
첫 줄 규칙의 한가지 예외는 소스 코드가 유닉스 “셔뱅 (shebang)” 줄 로 시작하는 경우입니다.
셔뱅을 통해 파이썬 버전을 지정하면 실행 시점에 자동으로 선택해줍니다.
•
Body는 들여쓰기가 된다. 파이썬에서 들여쓰기는 문장을 덩어리로 묶는 방법으로 들여쓰는 방법은 탭이나 공백으로 같은 양만큼 들여쓰기 해야하며 블록을 끝낼 땐 빈 줄을 입력해야 한다.
Chapter2. 소개
•
변수
◦
= : 변수에 값을 대입
◦
_ : 마지막에 인쇄된 표현식이 대입되는 변수 (Read Only)
◦
a, b = 0, 1 처럼 다중 대입 가능
•
숫자
◦
int : 정수
◦
float : 소수 ( division 은 float 반환)
◦
** : 거듭제곱 (- 보다 우선순위가 높음)
◦
Decimal : ?
◦
Fraction : ?
◦
j or J : 허수부를 가리키는 접미사
◦
0 이 아닌 모든 정수는 true, 0은 false
•
문자열
◦
‘’ 또는 “”로 문자열 사용 가능
◦
\ 로 이스케이핑 가능
◦
‘’ 안에 “”와 “” 안에 ‘’는 각각 문자로 인식
◦
따옴표 앞에 r을 붙이면 역슬래시를 일반 문자로 사용가능
◦
‘’’…’’’ 또는 “””…””” 를 통해 멀티라인 가능하고 줄바꿈을 무시하려면 \ 사용
◦
문자열끼리 +로 이어 붙일 수 있고 *로 반복 가능하고 문자열이 나열되면 + 생략 가능 (변수나 표현식에 문자열을 붙이고 싶다먼 꼭 +를 붙여야함)
•
문자열 서브 스크립트
◦
Python[0] 처럼 문자열은 인덱스될 수 있음
◦
인덱스는 0부터 시작, -1은 끝에서부터 시작
◦
Python[0:2] 와 같이 슬라이싱도 가능하고 시작과 끝 슬라이스 인덱스는 각각 생략 가능하고 제일 처음과 끝 인덱스로 대체됨
◦
s[:i] + s[i:] 는 항상 s와 같음
◦
인덱스로 문자열 길이를 넘는 숫자를 사용하는 것은 에러지만 슬라이스 인덱스로 사용하는 것은 자연스럽게 처리됨
◦
문자열은 불변이기 때문에 문자열을 인덱스로 참조한 위치에 대입하는건 에러
•
참, 거짓
◦
자료형이 비어 있다면 False, 비어있지 않다면 True입니다.
◦
bool() 연산을 통해 참인지 거짓인지 알 수 있습니다.
◦
bool은 int의 서브클래스입니다.
True | “Python” | [1, 2, 3] | (1, 2, 3) | {’a’: 1} | 1 | |
False | “” | [] | () | {} | 0 | None |
•
리스트
◦
list = [1, 4, 9] 처럼 대괄호 사이에 쉼표로 구분된 값들의 목록
◦
서로 다른 형의 항목들을 포함할 수 있지만 항목들이 같은 형이 대부분
◦
리스트 또한 인덱싱과 슬라이싱이 가능
◦
list[:] 는 얕은 복사본을 반환
◦
list + [2, 3, 8] 같은 이어붙이기 연산 가능
◦
불변인 문자열과 달리 리스트는 가변이므로 인덱스로 참조한 위치에 대입 가능
◦
list[1:3] = [5] 처럼 슬라이스에 대입 가능
◦
list[:] = [] 처럼 삭제 가능
◦
list2 = [0, list1] 처럼 리스트를 포함하는 리스트 중첩 가능
◦
길이가 0이 아닌 리스트는 true, 길이가 0인 리스트는 false
Chapter3. 문법
•
연산자
◦
대입 연산자
▪
표현식 안에서의 대입은 바다 코끼리 연산자 :=를 사용합니다.
◦
비교 연산자
▪
비교는 연쇄할 수 있습니다. a < b == c 는 a가 b보다 작고 동시에 b가 c와 같은지 검사합니다.
▪
시퀀스 객체들은 보통 같은 시퀀스 형의 다른 객체들과 비교될 수 있습니다.
이 때 비교는 사전식 순서를 사용합니다.
◦
논리 연산자
▪
우선순위는 not > and > or 순서입니다.
▪
논리 연산자 and 와 or을 사용해 비교를 결합할 수 있고
비교의 결과는 not으로 부정될 수 있습니다.
▪
논리 연산자는 단락-회로 연산자로 왼쪽에서 오른쪽으로 값이 구해지고
결과가 결정되면 값 구하기가 중단됩니다.
•
if문
if expression:
...
elif expression:
...
elif expression:
...
else
...
Python
복사
•
for문
◦
시퀀스를 이터레이션하는 문법
words = ['a', 'b', 'c']
for word in words:
...
Python
복사
◦
컬렉션을 이터레이션하는 문법
# 샘플 컬렉션
words = {'a':'apple', 'b':'banana', 'c':'cat'}
# 컬렉션의 복사본으로 루프하는 방식
for alphabet, word in words.copy().items():
if word == 'apple':
del words[alphabet]
# 새 컬렉션을 만드는 방식
apples = {}
for alphabet, word in words.item():
if word == 'apple':
apples[alphabet] = word
Python
복사
◦
숫자 시퀀스를 이터레이션하는 문법
# 끝값은 포함되지 않는다
for i in range(5):
...
# 범위를 지정할 수도 있다
for i in list(range(5, 10)):
...
# 시퀀스의 인덱스로 이터레이션하는 방법
word = ['apple', 'banana', 'cat']
for i in range(len(word)):
print(i, word[i])
Python
복사
range()가 돌려주는 객체는 리스트가 아니고 이터러블이다.
•
for문의 break문, continue문, else절
◦
break문
for x in range(2, n):
if n % x == 0:
break
Python
복사
◦
continue문
for num in range(2, 10):
if num % 2 == 0:
continue
Python
복사
◦
else절
# 이터러블이 소진된 경우 작동
for i in range(5):
...
else:
...
# 조건이 거짓인 경우 작동
while False:
...
else:
...
Python
복사
•
pass문
# 특별히 수행할 일이 없는 경우
while True:
pass
# 최소한의 클래스를 만들 경우
class EmptyClass:
pass
# TODO용으로 사용하는 경우
def initlog(*args):
pass #Remember to implement this
Python
복사
•
match문
# 특정 값에 매치되는 경우
match status:
case 400:
return "Bad Request"
case 404:
return "Not found"
case _: # 와일드 카드(default)
return "Something's wrong with the internet"
# 여러 값에 매치되는 경우
case 401 | 403 | 404:
return "Not allowed"
# 튜플인 경우
match point:
case (0, 0):
print("Origin")
case (x, y):
print(f"X={x}, Y={y}")
# 가드 패턴(if)를 사용할 경우
match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
case Point(x, y):
print(f"Not on the diagonal")
Python
복사
•
def
# 함수의 인자들은 Call by Value로 항상 객체 참조
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b , a+b
print()
>>> fib(2000)
# 키워드 인자를 사용할 경우
def parrot(voltage, state='a stiff', action='voom'):
# 가변 인자를 사용할 경우
def cheeseshop(kind, *args, **keywords):
# 람다 표현식을 사용할 경우
def make_incrementor(n):
return lambda x: x + n
# 도큐멘테이션 문자열을 사용할 경우
def my_function():
"""Do nothing, but document it.
No, really, it doesn't do anyting.
"""
pass
>>> print(my_function.__doc__)
# 가능
>>> parrot(1000) # 위치 인자
>>> parrot('a million', 'bereft of life', 'jump') # 위치 인자 여러 개
>>> parrot(voltage=1000) # 키워드 인자 1개
>>> parrot(action='voooom', voltage=100) # 키워드 인자 2개(위치 상관 X)
>>> parrot('a thousand', state='pushing up the daisies') # 위치 인자와 키워드 인자
>>> cheeseshop("kind", "arg1", "arg2", keyword1="A", keyword2="B") # 가변 인자
# 불가능
>>> parrot() # 필수 인자 없음
>>> parrot(voltage=5.0, 'dead') # 키워드 인자 뒤 위치 인자 불가능
>>> parrot(110, voltage=220) # 인자 중복
>>> parrot(actor='John') # 없는 키워드 인자
>>> cheeseshop("kind", keyword1="A", keyword2="B", "arg1", "arg2") # **keywrods는 *args 뒤에 와야함
Python
복사
◦
return 문이 없는 함수는 None을 반환한다.
◦
python에서 함수는 overloading이 없어도 그런 것처럼 호출할 수 있다.
◦
특수 인자 / 와 * 는 위치 전용 인자와 키워드 전용 인자를 구분하기 위해 사용한다.
•
코드 스타일
◦
들려 쓰기에 4-스페이스를 사용하고, 탭을 사용하지 마세요.
◦
79자를 넘지 않도록 줄 넘김 하세요.
◦
함수, 클래스, 함수 내의 큰 코드 블록 사이에 빈 줄을 넣어 분리하세요. 가능하다면, 주석은 별도의 줄로 넣으세요.
◦
독스트링을 사용하세요.
◦
연산자들 주변과 콤마 뒤에 스페이스를 넣고, 괄호 바로 안쪽에는 스페이스를 넣지 마세요: a = f(1, 2) + g(3, 4).
◦
클래스와 함수들에 일관성 있는 이름을 붙이세요. 관례는 클래스의 경우 UpperCamelCase, 함수와 메서드의 경우 lowercase_with_underscores입니다. 첫 번째 메서드 인자의 이름으로는 항상 self를 사용하세요.
◦
여러분의 코드를 국제적인 환경에서 사용하려고 한다면 특별한 인코딩을 사용하지 마세요. 어떤 경우에도 파이썬의 기본, UTF-8, 또는 단순 ASCII조차, 이 최선입니다.
◦
마찬가지로, 다른 언어를 사용하는 사람이 코드를 읽거나 유지할 약간의 가능성만 있더라도, 식별자에 ASCII 이외의 문자를 사용하지 마세요.
Chapter4. 자료 구조
•
리스트 (list)
>>> fruits = ['orange', 'apple', 'pear']
Python
복사
◦
list.append(x)
▪
리스트 끝에 항목을 더합니다. a[len(a):] = [x]와 동등
>>> fruits.append('grape')
>>> fruits
['orange', 'apple', 'pear', 'grape']
Python
복사
◦
list.extend(iterable)
▪
리스트의 끝에 이터러블의 모든 항목을 덧붙여서 확장합니다. a[len(a):] = iterable와 동등
>>> animals = ['cat', 'dog']
>>> fruits.extend(animals)
>>> fruits
['orange', 'apple', 'pear', 'cat', 'dog']
Python
복사
◦
list.insert(i, x)
▪
주어진 위치(i)에 항목(x)을 삽입합니다. a.insert(len(a), x)는 a.append(x)와 동등
>>> fruits.insert(1, 'banana')
>>> fruits
['orange', 'banana', 'apple', 'pear']
Python
복사
◦
list.remove(x)
▪
리스트에서 값이 x와 같은 첫 번째 항목을 삭제합니다. 없으면 ValueError를 일으킵니다.
>>> fruits.remove('apple')
>>> fruits
['orange', 'pear']
Python
복사
◦
list.pop([i])
▪
리스트에서 주어진 위치에 있는 항목을 삭제하고, 그 항목을 돌려줍니다. 인덱스를 지정하지 않으면 리스트의 마지막 항목을 삭제하고 돌려줍니다.
>>> fruits.pop()
'pear'
Python
복사
◦
list.clear()
▪
리스트의 모든 항목을 삭제합니다. del a[:]와 동등
>>> fruits.clear()
>>> fruits
[]
Python
복사
◦
list.index(x, start, end)
▪
리스트에 있는 항목 중 값이 x와 같은 첫 번째 것의 0부터 시작하는 인덱스를 돌려줍니다. 없으면 ValueError를 일으킵니다.
>>> fruits.index('apple')
1
Python
복사
◦
list.count(x)
▪
리스트에서 x가 등장하는 횟수를 돌려줍니다.
>>> fruits.count('apple')
1
Python
복사
◦
list.sort(*, key=None, reverse=False)
▪
리스트의 항목들을 제자리에서 정렬합니다.
▪
형이 다른 데이터끼리는 정렬되지 않습니다.
>>> fruits.sort()
['apple', 'orange', 'pear']
Python
복사
◦
list.reverse()
▪
리스트의 요소들을 제자리에서 뒤집습니다.
>>> fruits.reverse()
['pear', 'orange', 'apple']
Python
복사
◦
list.copy()
▪
리스트의 얕은 사본을 돌려줍니다. a[:]와 동등
>>> fruits.copy()
['orange', 'apple', 'pear']
Python
복사
•
stack
◦
리스트 메서드들은 리스트를 스택으로 사용하기 쉽게 만듭니다.
◦
마지막에 넣은 요소가 처음으로 꺼내지는 요소입니다. (LIFO)
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
Python
복사
•
queue
◦
리스트를 큐로 사용하는 것도 가능하지만 리스트의 끝에 덧붙이거나 꺼내는 것은 빠르지만 리스트의 머리에 덧붙이거나 머리에서 꺼내는 것은 느립니다.
◦
큐를 구현하려면 양 끝에서의 덧붙이기와 꺼내기가 모두 빠른 collections.deque를 사용하세요.
◦
처음으로 넣은 요소가 처음으로 꺼내지는 요소입니다. (FIFO)
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
Python
복사
•
list comprehension
◦
리스트를 만드는 간결한 방법을 제공합니다.
◦
각 요소가 다른 시퀀스나 이터러블의 멤버들의 어떤 연산을 적용한 결과인 리스트를 만들거나 어떤 조건을 만족하는 요소들로 구성된 서브 시퀀스를 만듭니다.
◦
표현식과 그 뒤를 따르는 for절과 없거나 여러 개의 for 또는 if절들을 감싸는 대괄호로 구성됩니다. 그 결과 for과 if절의 문맥에서 표현식의 값을 구해서 만들어집니다.
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> squares = list(map(lambda x: x**2, range(10))) # 다른 방법 1
>>> squares = [x**2 for x in range(10)] # 다른 방법 2
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Python
복사
•
del
◦
list.remove와 다르게 값대신 인덱스를 사용해 항목을 삭제할 수 있다
◦
변수 자체를 삭제할 수도 있다
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
>>> del a # 변수 삭제
Python
복사
•
튜플 (tuple)
◦
튜플은 쉼표로 구성되는 시퀀스 자료형입니다.
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
# 시퀀스 언패킹
>>> t = 12345, 54321, 'hello!'
>>> x, y, z = t
>>> x
12345
# 중첩 튜플
>>> u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
# 튜플은 불변
>>> t[0] = 88888
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
# 튜플은 가변 객체를 담을 수 있다.
>>> v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
# 비었거나 하나의 항목을 갖는 튜플
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
Python
복사
◦
튜플과 리스트의 차이점
튜플 | 불변 | 이질적인 요소들의 시퀀스 | 언패킹이나 인덱싱으로 액세스 | () |
리스트 | 가변 | 등질적인 요소들의 시퀀스 | 이터레이션으로 액세스 | [] |
•
집합 (set)
◦
중복되는 요소가 없는 순서 없는 컬렉션입니다.
◦
합집합, 교집합, 차집합, 대칭 차집합 같은 수학 연산들도 지원합니다.
# 집합을 만들 땐 중괄호나 set()
>>> s = {'a', 'b', 'c'}
>>> s = set()
# 빈 집합을 만들 땐 {} 불가능
>>> s = {}
# 사용 예제
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False
# Demonstrate set operations on unique letters from two words
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
Python
복사
•
딕셔너리 (map)
◦
키가 중복되지 않는 키:값 쌍의 집합
◦
문자열과 숫자 같은 불변형은 키로 사용 가능
◦
문자열, 숫자, 튜플을 포함하는 튜플은 키로 사용 가능
◦
직접적이나 간접적으로 가변객체를 참조하는 튜플은 키로 사용 불가능
◦
리스트는 키로 사용 불가능
◦
이미 존재하는 키에 값을 대입할 경우 덮어씌워진다
# dict() 생성자를 이용해 딕셔너리 생성
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
# 딕셔너리 사용 예제
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
Python
복사
•
루프 테크닉
◦
items() : 딕셔너리로 루핑할 때 키와 거기에 대응하는 값을 동시에 얻을 수 있습니다.
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
... print(k, v)
...
gallahad the pure
robin the brave
Python
복사
◦
enumerate() : 시퀀스를 루핑할 때 위치 인덱스와 대응하는 값을 동시에 얻을 수 있습니다.
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
Python
복사
◦
zip() : 둘 이상의 시퀀스를 동시에 루핑할 때 엔트리들의 쌍을 만들 수 있습니다.
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
Python
복사
◦
reversed() : 시퀀스를 루핑할 때 거꾸로 루핑할 수 있습니다.
>>> for i in reversed(range(1, 10, 2)):
... print(i)
...
9
7
5
3
1
Python
복사
◦
sorted() : 시퀀스를 루핑할 때 정렬된 순서로 루핑할 수 있습니다.
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for i in sorted(basket):
... print(i)
...
apple
apple
banana
orange
orange
pear
Python
복사
◦
set() : 시퀀스에 대해 중복 요소를 제거합니다. sorted()와 함께 사용하면 고유한 요소를 정렬된 순서로 루핑할 수 있습니다.
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print(f)
...
apple
banana
orange
pear
Python
복사
◦
루프를 돌고 있는 리스트를 변경해야할 땐 새 리스트를 만드는 것이 더 간단하고 안전합니다.
>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]
Python
복사
Chapter5. 패키지와 클래스
•
패키지
# 계층적 패키지 예시
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
# 패키지로부터 서브 모듈 임포트 (전체 이름 참조)
import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
# from을 사용해 서브 모듈 임포트 (패키지 접두어 없이 사용)
from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
# 원하는 함수나 변수를 직접 임포트 (함수나 변수 직접 사용)
from sound.effects.echo import echofilter
echofilter(input, output, delay=0.7, atten=4)
# 패키지 내부 간의 임포트
from . import echo
from .. import formats
from ..filters import equalizer
Python
복사
◦
패키지를 임포트할 때 파이썬은 sys.path에 있는 디렉터리를 검색하면서 패키지 서브 디렉터리를 찾습니다.
◦
디렉터리를 패키지로 취급하게 만들기 위해선 __init__.py 파일이 필요합니다.
◦
from package import *를 사용하기 위해선 __init__.py파일에 __all__ 이라는 이름의 목록을 제공해야합니다.
제공하지 않는 경우 서브 모듈이 아닌 패키지만을 임포트하고 __init__.py의 초기화 코드를 실행합니다.
◦
__path__.py는 __init__.py을 실행하기 전에 파일이 들어있는 디렉터리의 이름을 포함하는 리스트로 초기화됩니다.
•
클래스
◦
객체는 개체성을 갖고 여러 개의 이름이 여러 개의 스코프에서 같은 객체에 연결될 수 있습니다.
◦
파이썬의 스코프 규칙
▪
네임스페이스는 이름에서 객체로 가는 매핑으로 딕셔너리로 구현되어 있습니다.
▪
내장 이름들(함수, 내장 예외 이름), 모듈의 전역 이름들, 지역 이름들, 객체의 어트리뷰트 집합들이 네임스페이스를 이룹니다.
▪
네임스페이스끼리는 아무런 관계가 없습니다.
▪
네임스페이스들은 서로 다른 순간에 만들어지고 서로 다른 수명을 갖습니다.
▪
변수를 찾는 순서는 지역 네임스페이스 → 전역 네임스페이스 → 빌트인 네임스페이스입니다.
◦
global과 nonlocal
▪
global : 전역 네임스페이스에 선언된 변수를 참조하겠다는 키워드
▪
nonlocal : 현재 네임스페이스에 선언된 변수를 상위 스코프에서 찾아달라는 키워드
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
>>> scope_test()
>>> print("In global scope:", spam)
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
Python
복사
◦
클래스 객체
▪
어트리뷰트 참조와 인스턴스 만들기 두 가지 연산을 지원합니다.
>>> class Complex:
... # __init__() 를 통해 생성자를 만들 수 있음
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Python
복사
◦
인스턴스 객체
▪
어트리뷰트(데이터, 메서드) 참조만을 지원합니다.
>>> class MyClass:
... def f():
... ...
...
>>> x = MyClass()
>>> x.f() # 메서드 참조, 메서드 객체
>>> MyClass.f() # 함수 참조, 함수 객체
Python
복사
◦
메서드 객체
▪
메서드는 인스턴스 객체가 함수의 첫 번째 인자로 전달됩니다.
▪
메서드 객체는 인스턴스 객체와 함수 객체를 가리키는 포인터를 추상 객체에 함께 묶어서 만듭니다.
x.f() == MyClass.f(x)
Python
복사
◦
클래스와 인스턴스 변수
▪
클래스 변수 : 해당 클래스의 모든 인스턴스에서 공유되는 변수
▪
인스턴스 변수 : 인스턴스별 데이터를 위한 변수
▪
가변 객체의 경우엔 클래스 변수가 아닌 인스턴스 변수로 사용해야 합니다.
▪
클래스와 인스턴스 모두에서 같은 어트리뷰트 이름이 등장하면 인스턴스를 우선적으로 조회합니다.
◦
클래스 상속
▪
클래스 객체가 만들어질 때 베이스 클래스가 기억되고 어트리뷰트를 참조할 때 베이스 클래스로 검색을 확장합니다.
▪
다중 상속에선 Base1부터 순서대로 찾습니다.
# 클래스 상속 방법
class DerivedClassName(BaseClassName):
# 다른 모듈에 정의된 클래스 상속 방법
class DerivedClassName(modname.BaseClassName):
# 다중 상속 방법
class DerivedClassName(Base1, Base2, Base3):
# 인스턴스형을 검사하는 방법
isinstance(classA, type)
# 클래스 상속을 검사하는 방법
issubclass(classA, classB)
Python
복사
◦
비공개 변수
▪
변수 이름 앞에 밑줄 두 개 __를 붙이면 클래스 밖에서 접근할 수 없는 비공개 변수를 만들 수 있습니다.
◦
데이터 클래스
from dataclasses import dataclass
@dataclass
class Employee:
name: str
dept: str
salary: int
>>> john = Employee('john', 'computer lab', 1000)
>>> john.dept
'computer lab'
>>> john.salary
1000
Python
복사
◦
이터레이터
▪
클래스에 __iter__와 __next__를 정의하여 이터레이터를 구현할 수 있습니다.
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
... print(char)
...
m
a
p
s
Python
복사
◦
제네레이터
▪
이터레이터를 쉽게 만들어주는 도구입니다.
▪
yield문을 사용하면 제네레이터가 되고 yield에는 값을 지정합니다.
▪
제네레이터 객체에서 __next__를 호출할 때마다 함수 안의 yield까지 코드를 실행하며 yield에서 값을 발생시킵니다.
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
>>> for char in reverse('golf'):
... print(char)
...
f
l
o
g
Python
복사
Chapter6. 모듈
•
모듈의 소개
◦
인터프리터를 종료한 후에 다시 들어가면 정의했던 함수나 변수들이 사라집니다.
◦
정의들을 파일에 넣고 스크립트나 인터프리터의 대화형 모드에서 사용할 수 있는 방법을 제공하고
이런 파일을 모듈이라고 부릅니다.
◦
모듈로부터 정의들이 다른 모듈이나 메인 모듈로 임포트될 수 있습니다.
◦
모듈은 확장자 .py를 붙입니다 모듈 내에서 모듈의 이름은 전역 변수 __name__으로 제공됩니다.
◦
각 모듈에는 고유한 개인 네임스페이스가 있으므로 충돌에 대해 걱정하지 않고 사용할 수 있습니다.
>>> import fibo
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
>>> local = fibo.fib # 지역 변수에 대입 가능
>>> local(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Python
복사
•
import문
◦
효율성의 이유로 각 모듈은 인터프리터 세션마다 한 번만 임포트됩니다.
◦
모듈을 수정하면 인터프리터를 다시 키거나 importlib.reload(modulename)를 사용해야 합니다.
# 모듈의 네임스페이스로부터 직접적으로 모듈의 이름을 가져오는 import문
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
# * 을 사용하면 밑줄(_)로 시작하는 것들을 제외한 모든 이름을 임포트함
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
# 모듈 이름 다음 as가 올 경우 as 다음의 이름을 임포트한 모듈에 직접 연결함
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Python
복사
•
모듈을 스크립트로 실행하기
◦
모듈에 def문을 통한 정의만 있다면 임포트될 때 코드가 실행되지 않습니다.
◦
모듈의 끝에 아래 코드를 붙인 후 모듈을 메인 파일로 실행하면 스크립트로 실행할 수 있습니다.
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
Python
복사
$ python fibo.py <arguments>
Python
복사
•
모듈의 검색 경로
◦
모듈을 가져오면 인터프리터는 먼저 해당 이름을 가진 내장 모듈을 sys.builtin_module_names에서 검색합니다.
◦
찾지 못하면 sys.path 변수로 지정된 디렉터리 목록에서 검색합니다.
◦
sys.path는 다음 위치에서 초기화됩니다.
▪
입력 스크립트를 포함하는 디렉터리 (또는 파일이 지정되지 않았을 때는 현재 디렉터리)
▪
PYTHONPATH (디렉터리 이름들의 목록, 셸 변수 PATH와 같음)
▪
설치 종속 기본값
•
컴파일 캐싱
◦
모듈 로딩을 빠르게 하기 위해 __pycache__ 디렉터리에 각 모듈의 컴파일된 버전을 module.version.pyc라는 이름으로 캐싱합니다.
◦
파이썬이 캐시를 검사하지 않는 상황
▪
명령행에서 직접 로드되는 모듈들은 항상 재컴파일하고 그 결과를 저장하지 않습니다.
▪
소스 모듈이 없으면 캐시를 검사하지 않습니다.
◦
컴파일된 모듈의 크기를 줄이려면 명령줄에 -O나 -OO인자를 사용해 assert문과 __doc__ 문자열을 제거합니다.
◦
모듈을 최적화하기 위해선 opt- 태그를 사용합니다.
◦
.py 파일에서 읽을 때보다 .pyc 파일에서 읽을 때 더 빨리 실행되는게 아니라 로드 속도만 빨라집니다.
•
표준 모듈
◦
sys 는 모든 파이썬 인터프리터에 내장됩니다.
>>> import sys
>>> sys.ps1 # 기본 프롬프트 문자
'>>> '
>>> sys.ps2 # 보조 프롬프트 문자
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
Python
복사
•
dir()
◦
모듈이 정의하는 이름들을 찾는데 사용합니다.
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
'__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
'warnoptions']
Python
복사
Chapter7. 입력과 출력
•
문자 출력
◦
포맷 문자열 리터럴
▪
문자열에 f 또는 F 접두어를 붙이고 표현식을 {expression}으로 작성하여 문자열에 파이썬 표현식의 값을 삽입합니다.
▪
: 뒤에 정수를 전달하면 해당 필드의 최소 문자 폭이 됩니다.
▪
!a 는 ascii(), !s 는 str(), !r 는 repr()로 포맷되기 전에 값을 변환할 수 있습니다.
▪
= 는 변수의 값으로 표현식을 확장할 수 있습니다.
>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
The value of pi is approximately 3.142.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print(f'{name:10} ==> {phone:10d}')
...
Sjoerd ==> 4127
Jack ==> 4098
Dcab ==> 7678
>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.
>>> bugs = 'roaches'
>>> count = 13
>>> area = 'living room'
>>> print(f'Debugging {bugs=} {count=} {area=}')
Debugging bugs='roaches' count=13 area='living room'
Python
복사
◦
문자열 format() 메서드
# 기본 사용법
>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"
# 위치 지정 사용
>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam
# 이름 지정 사용
>>> print('This {food} is {adjective}.'.format(food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.
# 위치 지정과 이름 지정의 혼용
>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))
The story of Bill, Manfred, and Georg.
# []를 이용해 딕셔너리의 키를 액세스
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
# **를 이용해 딕셔너리를 키워드 인수로 전달
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
Python
복사
◦
수동 문자열 포매팅
▪
print() 의 동작 방식으로 인해 각 컬럼 사이에 스페이스 하나가 추가됩니다.
▪
str.rjust() 메서드는 왼쪽에 스페이스를 채워 주어진 폭으로 문자열을 우측 줄 맞춤합니다.
▪
str.ljust() 메서드는 오른쪽에 스페이스를 채워 좌측 줄 맞춤합니다.
▪
str.center() 메서드는 양쪽에 스페이스를 채워 가운데 줄 맞춤합니다.
▪
str.zfill() 메서드는 숫자 문자열의 왼쪽에 0을 채웁니다.
>>> for x in range(1, 11):
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
... # Note use of 'end' on previous line
... print(repr(x*x*x).rjust(4))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
Python
복사
◦
예전의 문자열 포매팅
▪
% 연산자는 문자열 포매팅에도 사용할 수 있습니다.
string % values가 주어지면 % 인스턴스는 0개 이상의 values 요소로 대체됩니다.
>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.
Python
복사
•
파일 입출력
◦
open() 메서드는 파일 객체를 반환하고 open(filename, mode, encoding=None) 의 형태로 주로 사용합니다.
◦
mode에는 기본값인 읽기 r, 작성 w, 추가 a, 읽고 쓰기 r+, 바이너리 모드 b가 있습니다.
◦
encoding은 기본적으로 UTF-8을 사용하고 바이너리 모드에선 인코딩을 지정할 수 없습니다.
◦
파일 객체를 다룰 때 도중 예외가 발생하더라도 올바르게 닫히기 때문에 with 키워드를 사용하는 것이 좋습니다.
◦
with 키워드를 사용하지 않으면 close()를 호출해 파일을 닫고 시스템 자원을 즉시 반납해야 합니다.
>>> f = open('workfile', 'w', encoding="utf-8")
>>> with open('workfile', encoding="utf-8") as f:
... read_data = f.read()
# We can check that the file has been automatically closed.
>>> f.closed
True
Python
복사
•
파일 객체의 메서드
◦
read(size)
▪
일정량의 데이터를 읽고 문자열(텍스트 모드)이나 바이트열(바이너리 모드)로 돌려줍니다.
▪
size는 선택적인 숫자 인자로 생략되거나 음수면 파일의 내용 전체를 읽어서 돌려줍니다.
▪
파일의 끝에 도달하면 read()는 빈 문자열을 돌려줍니다.
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
Python
복사
◦
readline()
▪
파일에서 한 줄을 읽고 문자열 끝에 개행 문자 \n가 보존됩니다.
▪
파일의 마지막 줄에선 개행 문자가 생략됩니다.
▪
파일의 끝에 도달하면 빈 문자열을 돌려주지만 빈 줄은 개행 문자만 포함됩니다.
▪
파일의 모든 줄을 리스트로 읽어 들이려면 list(f)나 f.readlines()를 사용할 수 있습니다.
>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
Python
복사
◦
write(string)
▪
내용을 파일에 쓰고 출력된 문자들의 개수를 돌려줍니다.
▪
다른 형의 객체들은 쓰기 전에 문자열(텍스트 모드)이나 바이트열 객체(바이너리 모드)로 변환되어야 합니다.
>>> f.write('This is a test\n')
15
>>> value = ('the answer', 42)
>>> s = str(value) # convert the tuple to string
>>> f.write(s)
18
Python
복사
◦
tell()
▪
파일의 현재 위치를 가리키는 정수를 돌려줍니다.
▪
바이너르 모드의 경우 파일의 처음부터의 바이트 수로 표현되고
텍스트 모드의 경우 불투명한 숫자입니다.
◦
seek(offset, whence)
▪
파일 객체의 위치를 바꾸는데 사용합니다.
▪
위치는 기준점에 offset을 더해서 계산됩니다.
▪
기준점은 whence 인자로 선택합니다. (생략가능)
0(default)이면 파일의 처음부터 1이면 현재 파일 위치를 2면 파일의 끝을 기준점으로 사용합니다.
>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5) # Go to the 6th byte in the file
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # Go to the 3rd byte before the end
13
>>> f.read(1)
b'd'
Python
복사
•
json으로 구조적인 데이터를 저장하기
◦
dumps() 메서드를 통해 객체를 직렬화 할 수 있습니다.
◦
dump() 메서드는 객체를 텍스트 파일로 직렬화합니다.
◦
load() 메서드를 통해 객체로 다시 역직렬화 할 수 있습니다.
◦
JSON 파일은 반드시 UTF-8로 인코딩되어야 합니다.
>>> import json
# 객체를 직렬화
>>> x = [1, 'simple', 'list']
>>> json.dumps(x)
'[1, "simple", "list"]'
# 텍스트 파일로 객체를 직렬화
>>> json.dump(x, f)
# 파일을 객체로 역직렬화
>>> x = json.load(f)
Python
복사
Chapter8. 에러와 예외
•
문법 에러 (파싱 에러)
◦
문제가 되는 줄을 다시 보여주고 줄에서 에러가 감지된 가장 앞의 위치를 가리키는 작은 화살표를 표시합니다.
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
Python
복사
•
예외
◦
실행 중에 감지되는 에러들을 예외라고 부릅니다.
◦
표준 예외 이름은 예약 키워드가 아닌 내장 식별자입니다.
◦
줄의 나머지 부분은 예외의 형과 원인에 기반을 둔 상세 명세를 제공합니다.
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
Python
복사
•
예외 처리
# 기본 구조
try:
...
except: # 어떠한 오류든 핸들링
...
except 발생오류: # 특정 오류 핸들링
...
except (발생오류1, 발생오류2, 발생오류3): # 여러 개의 오류 핸들링
...
except 발생오류 as 오류변수: # 오류를 변수에 담아 사용
...
else: # 일치하는 except절이 없을 시 실행
...
finally: # 무조건 실행
...
# 사용 예시
>>> while True:
... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
# pass를 통해 예외 회피
try:
...
except:
pass
Python
복사
•
예외 만들기
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere
Python
복사
•
예외 체인
◦
from을 통해 예외의 연쇄관계를 만들어줄 수 있습니다.
◦
from None은 연쇄관계를 끊습니다.
>>> try:
... raise ConnectionError
... except ConnectionError as exc:
... raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in func
ConnectionError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database
Python
복사
•
사용자 정의 예외
◦
새 예외 클래스를 만들어 이름을 붙일 수 있습니다.
◦
대부분의 예외는 표준 예외들의 이름들과 유사하게 Error로 끝나는 이름으로 정의됩니다.
◦
예외는 보통 직접적으로나 간접적으로 Exception 클래스를 계승합니다.
•
멀티 예외
# ExceptionGroup을 통한 멀티 예외 rasing & handling
>>> def f():
... excs = [OSError('error 1'), SystemError('error 2')]
... raise ExceptionGroup('there were problems', excs)
...
>>> f()
+ Exception Group Traceback (most recent call last):
| File "<stdin>", line 1, in <module>
| File "<stdin>", line 3, in f
| ExceptionGroup: there were problems
+-+---------------- 1 ----------------
| OSError: error 1
+---------------- 2 ----------------
| SystemError: error 2
+------------------------------------
>>> try:
... f()
... except Exception as e:
... print(f'caught {type(e)}: e')
...
caught <class 'ExceptionGroup'>: e
>>>
# except*을 통해 ExceptionGroup 중 특정 예외만 handling
>>> def f():
... raise ExceptionGroup("group1",
... [OSError(1),
... SystemError(2),
... ExceptionGroup("group2",
... [OSError(3), RecursionError(4)])])
...
>>> try:
... f()
... except* OSError as e:
... print("There were OSErrors")
... except* SystemError as e:
... print("There were SystemErrors")
...
There were OSErrors
There were SystemErrors
+ Exception Group Traceback (most recent call last):
| File "<stdin>", line 2, in <module>
| File "<stdin>", line 2, in f
| ExceptionGroup: group1
+-+---------------- 1 ----------------
| ExceptionGroup: group2
+-+---------------- 1 ----------------
| RecursionError: 4
+------------------------------------
>>>
Python
복사
•
예외 메모
◦
add_note() 메서드를 통해 stacktrace에 메모를 추가할 수 있습니다.
>>> try:
... raise TypeError('bad type')
... except Exception as e:
... e.add_note('Add some information')
... e.add_note('Add some more information')
... raise
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: bad type
Add some information
Add some more information
>>>
Python
복사
Chapter9. 가상 환경 및 패키지
•
파이썬 응용 프로그램은 종종 표준 라이브러리로 제공되지 않는 패키지와 모듈을 사용합니다.
이 때 특정 버전의 라이브러리가 필요할 수도 있는데 가상 환경으로 해결할 수 있습니다.
•
가상 환경을 만들고 관리하는데 사용되는 모듈은 venv입니다.
# tutorial-env라는 디렉토리를 만들고 안에 파이썬 인터프리터와 다양한 서포팅 파일들을 포함합니다.
python3 -m venv tutorial-env
Python
복사
•
가상 환경의 일반적인 디렉토리 위치는 .venv입니다.
# 가상 환경 활성화
$ source tutorial-env/bin/activate
# 가상 환경 비활성화
deactivate
Python
복사
•
pip로 패키지 관리하기
◦
패키지들을 설치, 업데이트, 삭제할 수 있는 프로그램입니다.
◦
https://pypi.org 로부터 패키지들을 설치합니다.
# pip install로 설치
(tutorial-env) $ python -m pip install novas
Collecting novas
Downloading novas-3.1.1.3.tar.gz (136kB)
Installing collected packages: novas
Running setup.py install for novas
Successfully installed novas-3.1.1.3
# == 과 버전를 붙여 특정 버전의 패키지 설치
(tutorial-env) $ python -m pip install requests==2.6.0
Collecting requests==2.6.0
Using cached requests-2.6.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.6.0
# 패키지를 최신 버전으로 업데이트
(tutorial-env) $ python -m pip install --upgrade requests
Collecting requests
Installing collected packages: requests
Found existing installation: requests 2.6.0
Uninstalling requests-2.6.0:
Successfully uninstalled requests-2.6.0
Successfully installed requests-2.7.0
# 패키지 삭제
(tutorial-env) $ python -m pip uninstall requests
# 패키지 정보 확인
(tutorial-env) $ python -m pip show requests
---
Metadata-Version: 2.0
Name: requests
Version: 2.7.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: me@kennethreitz.com
License: Apache 2.0
Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
Requires:
# 설치된 패키지 목록 확인
(tutorial-env) $ python -m pip list
novas (3.1.1.3)
numpy (1.9.2)
pip (7.0.3)
requests (2.7.0)
setuptools (16.0)
# 설치된 패키지 목록을 저장
(tutorial-env) $ python -m pip freeze > requirements.txt
(tutorial-env) $ cat requirements.txt
novas==3.1.1.3
numpy==1.9.2
requests==2.7.0
# 저장한 패키지 목록으로 패키지 설치
(tutorial-env) $ python -m pip install -r requirements.txt
Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
...
Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
...
Collecting requests==2.7.0 (from -r requirements.txt (line 3))
...
Installing collected packages: novas, numpy, requests
Running setup.py install for novas
Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0
Python
복사
Chapter10. 표준 라이브러리
•
내장 라이브러리
>>> dir() # 모듈의 모든 함수 리스트를 반환합니다.
>>> help() # 모듈 매뉴얼을 반환합니다.
Python
복사
•
운영 체제 인터페이스
>>> import os # from os import * 대신 import os 스타일을 사용해야 합니다.
>>> os.getcwd() # 현재 디렉토리를 반환합니다.
'C:\\Python3.11'
>>> os.chdir('/server/accesslogs') # 디렉토리 변경합니다.
>>> os.system('mkdir today') # 셸 명령어를 실행합니다.
0
>>> import shutil # 일상적인 파일과 디렉토리 관리 작업에 유용합니다.
>>> shuitl.copyfile('data.db', 'archive.db') # 파일을 작성한 날짜가 복사한 날짜로 변경
>>> shutil.copy('data.db', 'archive.db') # copyfile과 동일
>>> shutil.copy2('data.db', 'archive.db') # 파일의 메타정보도 복사
>>> shutil.copytree('./test1', './test2') # 폴더를 새로 만들며 하위 파일들도 복사
>>> shutil.move('/build/executables', 'installdir') # 파일 이동
Python
복사
•
파일 와일드카드
>>> import glob
>>> glob.glob('*.py') # 와일드카드 검색으로 파일 목록을 만듭니다.
['a.py', 'b.py', 'c.py']
Python
복사
•
명령행 인자
>>> import sys
>>> print(sys.argv) # 명령행 인자를 사용합니다.
['one', 'two', 'three']
>>> import argparse # 명령행 인자를 더욱 정교하게 처리합니다.
parser = argparse.ArgumentParser(prog = 'top', description = 'Show top lines from each file')
parser.add_argument('filenames', nargs = '+')
parser.add_argument('-l', '--lines', type = int, default = 10)
args = parser.parse_args()
print(args)
Python
복사
•
에러 출력 리디렉션과 프로그램 종료
>>> sys.stdin.readline() # 표준 입력
>>> sys.stdout.write() # 표준 출력
>>> sys.stderr.write('Warning') # 표준 에러 (버퍼 유무 외 표준 출력과 동일)
Python
복사
•
문자열 패턴 매칭
>>> import re # 문자열 처리를 위한 정규식 도구를 제공합니다.
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
Python
복사
•
수학
>>> import math
>>> math.cos(math.pi / 4)
0.70710678118654757
>>> math.log(1024, 2)
10.0
>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(range(100), 10)
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random()
0.17970987693706186
>>> random.randrange(6)
4
>>> import statistics
>>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
>>> statistics.mean(data)
1.6071428571428572
>>> statistics.median(data)
1.25
>>> statistics.variance(data)
1.3720238095238095
Python
복사
•
인터넷 엑세스
>>> from urllib.request import urlopen
>>> with urlopen('http://test.com/test.txt') as response:
... for line in response:
... line = line.decode()
... print(line.rstrip())
>>> import smtplib
>>> server = smtplib.SMTP('localhost')
>>> server.sendmail('from@test.com', 'to@test.com', """content""")
>>> server.quit()
Python
복사
•
날짜와 시간
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
>>> now.strftime(%m-%d-%y.)
'12-02-03.'
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday
>>> age.days
14368
Python
복사
•
데이터 압축
# zlib, gzip, bz2, lzma, zipfile, tarfile 등의 모듈이 있습니다.
>>> import zlib
>>> s = b'witch which has which witches wrist watch'
>>> len(s)
41
>>> t = zlib.compress(s)
>>> len(t)
37
>>> zlib.decompress(t)
b'witch which has which witches wrist watch'
>>> zlib.crc32(s)
226805979
Python
복사
•
성능 측정
>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791
Python
복사
•
품질 관리
def average(values):
"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0
"""
return sum(values) / len(values)
>>> import doctest # 독스트링에 내장된 테스트를 검사하는 도구를 제공합니다.
>>> doctest.testmod()
>>> import unittest # 더욱 포괄적인 테스트 집합을 별도의 파일로 관리할 수 있게 합니다.
class TestStatisticalFunctions(unittest.TestCase):
def test_average(self):
self.assertEqual(average([20, 30, 70]), 40.0)
self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
with self.assertRaises(ZeroDivisionError):
average([])
with self.assertRaises(TypeError):
average(20, 30, 70)
>>> unittest.main() # Calling from the command line invokes all tests
Python
복사