From 4b54f5feb4c1f3925e67dd7e9b847f4a693ce83e Mon Sep 17 00:00:00 2001 From: erun1012 Date: Sat, 11 Oct 2025 19:55:08 +0900 Subject: [PATCH 1/3] add session1 --- Chapter1/pythonic_code(1).md | 76 +++++++++++++++++++++ Chapter1/pythonic_code(2).md | 94 ++++++++++++++++++++++++++ Chapter1/pythonic_code(3).md | 53 +++++++++++++++ Chapter1/pythonic_code(4).md | 124 +++++++++++++++++++++++++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 Chapter1/pythonic_code(1).md create mode 100644 Chapter1/pythonic_code(2).md create mode 100644 Chapter1/pythonic_code(3).md create mode 100644 Chapter1/pythonic_code(4).md diff --git a/Chapter1/pythonic_code(1).md b/Chapter1/pythonic_code(1).md new file mode 100644 index 0000000..ac0f4f0 --- /dev/null +++ b/Chapter1/pythonic_code(1).md @@ -0,0 +1,76 @@ +## 1. 컴프리헨션 문법 +> 파이썬의 자료구조 데이터를 **간결하게** 생성할 수 있는 문법 + +### 리스트 컴프리헨션 +> 리스트를 만드는 간결한 방법을 제공 + +```python +numbers = [] +for i in range(5): + numbers.append(i*2) + +#컴프리헨션 표현 +numbers = [i*2 for i in range(5)] +# [0, 2, 4, 6, 8] + +#조건문을 넣어도 됨 +even = [i for i in range(10) if i % 2 == 0] +# [0, 2, 4, 6, 8] + +#if 중첩도 가능 +data = [i for i in range(1,11) if i % 2 == 0 if i<5] +# [0, 2, 4] +``` + +```python +date = [(x,y) for x in range(1,6) for y in range(1,4)] + +# for 문과 비교 +date2 = [] +for i in range(1,6): + for j in range(1,4): + data2.append((i,j)) + +# [(1, 1), (1, 2), (1, 3), +# (2, 1), (2, 2), (2, 3), +# (3, 1), (3, 2), (3, 3), +# (4, 1), (4, 2), (4, 3), +# (5, 1), (5, 2), (5, 3)] +``` + +### 딕셔너리 컴프리헨션 + +**유의할 점 : for문 앞에 키:값을 적는다는 것과 대괄호가 중괄호로 바뀐 것** + +```python +squares = [x: x**2 for x in range(5)] +# {0:0, 1:1, 2:4, 3:9, 4:16} +``` + +zip 함수 결합 +```python +name = ["왕춘삼", "김덕팔", "황갑득"] +age = [23, 14, 42] + +data = {key: value for (key, value) in zip(name, age) if value > 20} + +# 출력결과 +{'왕춘삼': 23, '황갑득': 42} +``` + +### 셋(집합) 컴프리헨션 + +**유의할 점 : 딕셔너리 컴프리헨션과 비슷, 키:값 형태가 아닌 것만 유의** + +```python +unique = {x%3 for x in range(10)} +# {0, 1, 2} +``` + +- 반복문 + 조건문을 한 줄로 표현가능 +- 가독성과 효율성 향상 +- **단, 복잡한 로직은 가독성을 해침** + + +참고 문서 +https://tibetsandfox.tistory.com/25 diff --git a/Chapter1/pythonic_code(2).md b/Chapter1/pythonic_code(2).md new file mode 100644 index 0000000..d23afb4 --- /dev/null +++ b/Chapter1/pythonic_code(2).md @@ -0,0 +1,94 @@ +## 2. 언패킹(Unpacking)과 제너레이터(Generator) + +### 언패킹 +> 여러 값을 한 번에 변수에 풀어 넣는 기능 + +```python +a, b, c = [1, 2, 3] +print(a,b,c) +# 1 2 3 + +#리스트나 튜플 등 반복 가능한 객체면 다 가능 +numbers = [1, 2, 3, 4, 5] +first, *middle, last = numbers +print(first, middle, last) +# 1 {2,3,4}, 5 +``` + +### 제너레이터 +>데이터를 필요할 때만 하나씩 생성하는 지연평가 방식 함수 +```python +def count_up_to(n): + for i in range(1,n+1): + yield i + +for num in count_up_to(5): + print(num) +#1, 2, 3, 4, 5 +``` +함수 안에 yield 키워드를 사용하면 제너레이터이다. +yield가 값을 생성(반환)하고, 함수의 상태는 유지된 채 중단되었다가 +다음 호출로 그 지점에서 재개된다. + +yield 키워드 +```python +def func(): + yield 1 + yield 2 + yield 3 + +foo = func() + +print(next(foo)) # 1 +print(next(foo)) # 2 +print(next(foo)) # 3 +``` +### return 과의 차이점 + +제너레이터 함수는 yield 를 통해 값을 반환. +next 메소드나 for문 순회 등을 통해 값들을 리턴받을 수 있음. +**yield가 호출된다고 해서 함수가 종료되는 것은 아님** + +제너레이터 내부에서 return을 사용하면 현재 값에 상관없이 StopIteration 예외 발생 + +```python +def func(): + print("1 리턴 전") + yield 1 + print("1 리턴 후, 2 리턴 전") + yield 2 + print("2 리턴 후, 3 리턴 전") + yield 3 + print("3 리턴 후") + + +foo = func() + +print(next(foo)) +print(next(foo)) +print(next(foo)) + +1 리턴 전 +1 +1 리턴 후, 2 리턴 전 +2 +2 리턴 후, 3 리턴 전 +3 +``` + + +표현식 : 리스트 컴프리헨션과 동일하지만 **[] 대신 () 사용** +-> 값을 즉시 모두 만들지 않음 + +```python +lst=[x*2 for x in range(5)] +gen=(x*2 for x in range(5)) +``` + +- 전체 시퀀스를 메모리에 올리지 않음 -> 큰 파일, 로그, 스트리밍 데이터 처리에 적합 +- 필요할 때만 계산 -> 파이프라인에서 불필요한 계산 회피 +- 로컬 변수로 상태를 유지하면서 반복 로직 구현 가능 +- **디버깅 복잡, 한 번만 소비 가능. 다시 쓰려면 재생성** + +참고 문서 +https://tibetsandfox.tistory.com/28 diff --git a/Chapter1/pythonic_code(3).md b/Chapter1/pythonic_code(3).md new file mode 100644 index 0000000..7809fa9 --- /dev/null +++ b/Chapter1/pythonic_code(3).md @@ -0,0 +1,53 @@ +## 매직 메서드 +> 클래스에 특수 동작을 정의하는 메서드 (자동 호출됨) / `__이름__` 형식 + +- `__str__` vs `__repr__` + +```python +class User: + def __init__(self, name): + self.name = name + + def __str__(self): + return f"User: {self.name}" # print()용 + + def __repr__(self): + return f"User(name='{self.name}')" # 개발자용 (디버깅) + +user = User("Gahee") +print(user) # User: Gahee +user # User(name='Gahee') +``` + +→ print(user) → `__str__` 호출 + +→ user → `__repr__` 호출 : 대화형 콘솔 or Jupyter 등 + +→ repr(user) → 명시적으로 `__repr__` 호출 + +→ str(user) → 명시적으로 `__str__` 호출 + +→ `__str__` 가 없으면 자동으로 `__repr__` 사용 + + +- `__eq__` (== 비교 연산자 오버라이드) + +```python +class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __eq__(self, other): + return self.x == other.x and self.y == other.y + +p1 = Point(1, 2) +p2 = Point(1, 2) +print(p1 == p2) # True +``` + +→ a == b 를 하면, 내부적으로 호출 + +→ 클래스에 `__eq__`를 안 만들면 ==는 ‘객체가 같은 메모리 주소를 가리키는지’ 비교 + +- `__add__` : a + b 를 하면 내부적으로 실행 +- `__len__` : len() 실행하면 내부에서 진짜 리스트의 길이를 반환 \ No newline at end of file diff --git a/Chapter1/pythonic_code(4).md b/Chapter1/pythonic_code(4).md new file mode 100644 index 0000000..71afacd --- /dev/null +++ b/Chapter1/pythonic_code(4).md @@ -0,0 +1,124 @@ +## 데코레이터(Decorator) +> 어떤 함수를 인자로 받아 꾸며준 후 다시 함수로 리턴하는 함수 +> 함수 내부에 변화 주지 않고 로직을 추가하고 싶을 때 사용 +**데코레이터는 꾸며주는 함수 내부에 직접적 수정이나 로직 변환 불가** + +```python +def hello(): + print("안녕!") + +def decorator(func): + def wrapper(): + print("함수 실행 전") + func() + print("함수 실행 후") + return wrapper + +decorated = decorator(hello) +decorated() + +# 함수 실행 전 +# 안녕! +# 함수 실행 후 +``` +어떤 함수를 데코레이터로 꾸며주려면 그 함수의 선언부 위에 @데코레이터명을 적어주면 됨 +@ 문법으로 더 깔끔하게 + +```python +def decorator(func): + def wrapper(): + print("시작") + func() + print("끝") + return wrapper + +@decorator +def greet(): + print("안녕 파이썬!") + +greet() + +# 시작 +# 안녕 파이썬! +# 끝ㅁ +``` + +예시 추가 +```python +def say_hello(): + print("Hello") + +def decorator(func): + def sentence(*args, **kwargs): + print("Nice to meet you") + return func(*args, **kwargs) + + return sentence + +@decorator +def say_hello(): + print("Hello") + +say_hello() + +# 실행 결과 +Nice to meet you +Hello +``` + +데코레이터 동작 파악 +```python +def decorator(func): #1 + def sentence(*args, **kwargs): #3 + print("Nice to meet you") #6 + return func(*args, **kwargs) #7 + + return sentence #4 + +@decorator #3 +def say_hello(): #2 + print("Hello") #8 + + +say_hello() #5 +``` +#1 decorator 함수를 선언 +#2 say_hello 함수 선언 +#3 say_hello 함수를 decorator 함수로 꾸며줌. 이는 variable = decorator(say_hello)와 동일함. 따라서 sentence 함수도 이때 선언 +#4 decorator 함수로 꾸며주었기에 say_hello 함수는 sentence 함수의 로직을 실행 +#5 say_hello 함수 실행 +#6 say_hello 함수는 sentence 함수의 로직을 가지고 있기 때문에 sentence 함수의 로직 실행 +#7 decorator로 꾸며준 함수인 say_hello 함수를 호출하여 리턴 +#8 호출된 say_hello 함수가 실행 + +class와 함께 사용도 가능 +```python +class Decorator: + def __init__(self, func): # 꾸며줄 함수를 매개변수로 전달 + self.func = func # 꾸며줄 함수를 속성에 저장 + + def __call__(self, *args, **kwargs): + print("Nice to meet you") + self.func() #속성에 저장된 함수 호출 + print(f"My name is {args[0]}") + + +@Decorator +def say_hello(): + print("Hello") + + +say_hello("Fox") + +#실행 결과 +Nice to meet you +Hello +My name is Fox +``` + +- 코드의 중복을 최소화하고 재사용성을 높일 수 있음 +- 가독성 높일 수 있음. 로직 수정이 필요할 때도 데코레이터만 수정하면 됨 +- **중첩해서 사용하면 디버깅 난이도 상승** + +참고문서 +https://tibetsandfox.tistory.com/10 From b4a5bac5079669774358390c0af507da58b00962 Mon Sep 17 00:00:00 2001 From: erun1012 Date: Sat, 7 Feb 2026 02:20:07 +0900 Subject: [PATCH 2/3] add_Unit4 --- Unit4/pythonic_code(1).md | 169 +++++++++++++++++++++++++++ Unit4/pythonic_code(2).md | 142 +++++++++++++++++++++++ Unit4/pythonic_code(3).md | 23 ++++ Unit4/pythonic_code(4).md | 233 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 567 insertions(+) create mode 100644 Unit4/pythonic_code(1).md create mode 100644 Unit4/pythonic_code(2).md create mode 100644 Unit4/pythonic_code(3).md create mode 100644 Unit4/pythonic_code(4).md diff --git a/Unit4/pythonic_code(1).md b/Unit4/pythonic_code(1).md new file mode 100644 index 0000000..85391c5 --- /dev/null +++ b/Unit4/pythonic_code(1).md @@ -0,0 +1,169 @@ +### 1. if 문 + +여러 개의 elif 문 가능, 들여쓰기로 구분함. + +```python +x=int(input("정수 하나 입력 : ")) + +if x>0: + print("Positive") +elif x==0: + print("0") +else: + x=0 + print("Negative") +``` +객체 내 요소의 존재 존재 여부로 True, False + +in, not in 으로 객체 내 특정 요소 존재 여부로 True, False + +→ 여기서 객체는 일반적으로 리스트, 문자열, 튜플, 딕셔너리 + + +### 2. for 문 + +반복 가능한 자료형 (리스트, 문자열)의 항목을 순서대로 이터레이트 + +```python +words = ['cat','dog','bird'] + +for w in words: + print(w,end=' ') + +# cat dog bird +``` + +컬렉션을 이터레이트 하는 동안 같은 컬렉션 수정 코드를 만들기도 함. + +```python +users={'Hans':'active','Eleo':'inactive','dong':'active'} + +# inactive 삭제하기 +for user, status in users.copy().items(): + if status == 'inactive' + del users[user] +**#copy() 를 쓰는 이유는 반복 중 원본 자료를 변경하지 않기 위함.** + +# active 컬렉션 새로 만들기 +active_users={} +for user, status in users.item(): + if status == 'active' + active_users[user]=status +``` +리스트 내포 가능, if 조건문 추가 가능 + +```python +c = 'abcde' +a = [val + '' for val in c] +# ['ak','bk','ck','dk','ek'] + +b = [val+'k' for val in c if val == 'c'] +# ['ck'] +``` + + +### 3. range 함수 + +수열을 만드는 함수 range(a,b,c) ⇒ a≤x function object(hello) +``` + +⇒ 변수에 대입, 인자로 전달, 리스트에 저장, 반환 가능 + +⇒ 함수 = 객체, 함수 이름 = 객체 가리키는 참조 변수 + +- return 문이 없는 함수도 None 이라는 값을 돌려줌, print 를 사용하면 확인 가능 \ No newline at end of file diff --git a/Unit4/pythonic_code(4).md b/Unit4/pythonic_code(4).md new file mode 100644 index 0000000..7c441a8 --- /dev/null +++ b/Unit4/pythonic_code(4).md @@ -0,0 +1,233 @@ +### 9. 함수 정의 더 보기 + +**(1) 기본 인자 값 parameter default value** + +- 디폴트 값, 함수 정의 시점에 정의되고 있는 스코프에서 구해짐. + +```python +i = 5 + +def f(arg=i): + print(arg) + +i = 6 +f() +# 5 +``` + +- 기본값은 한 번만 값이 구해진다. 리스트나 딕셔너리 같은 가변 객체가 차이를 가짐 + +```python +def f(a, L=[]): + L.append(a) + return L + +print(f(1)) +print(f(2)) +print(f(3)) + +# [1] +# [1, 2] +# [1, 2, 3] +``` + +- L=None 으로 쓰면 기본값이 공유되지 않음 +- 기본 매개변수를 항상 앞에 배치해야 함 + + +**(2) 키워드 인자** + +- 함수는 kwarg=value 형식의 키워드 인자를 사용해 호출될 수 있음 + +```python +def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): + +# 옳은 호출 +parrot(1000) # 1개의 위치 인자 +parrot(voltage=1000) # 1개의 키워드 인자 +parrot(voltage=1000000, action='VOOOOOM') # 2개의 키워드 인자 +parrot(action='VOOOOOM', voltage=1000000) # 2개의 키워드 인자 +parrot('a million', 'bereft of life', 'jump') # 3개의 위치 인자 +parrot('a thousand', state='pushing up the daisies') # 1개의 위치, 1개의 키워드 + +# 틀린 호출 +parrot() # 필수 인자 누락 +parrot(voltage=5.0, 'dead') # 키워드 인자 뒤에 키워드가 아닌 인자가 옴 +parrot(110, voltage=220) # 같은 인자가 중복됨 +parrot(actor='John Cleese') # 알려지지 않은 키워드 인자 +``` + +- 키워드 인자는 위치 인자 뒤에 와야함 + +```python +f(1,2,c=3) # 가능 +f(a=1,2) # 불가능 +``` + +- 키워드 인자의 순서는 중요하지 않음 +- 필수 인자도 키워드 인자로 전달할 수 있고 어떤 인자도 두 개 이상의 값을 받을 수 없음 +- **name 형식은 *name 형식 다음에 와야함 +- **name 형식의 마지막 형식 매개변수가 존재하면 형식 매개변수들에 대응하지 않는 모든 키워드 인자를 담은 딕셔너리를 받음 + + +**(3) 특수 매개 변수** + +인자는 위치나 명시적 키워드로 함수에 전달될 수 있음. 인자의 전달 방법을 제한할 수 있다. + +```python +def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): + ----------- ---------- ---------- + | | | + | 위치-키워드 | + | - 카워드 전용 + -- 위치 전용 + +``` + +- 위치-키워드 인자 : / 와 * 이 없으면 인자를 위치나 키워드로 함수에 전달 가능 +- 위치 전용 매개 변수 : / 앞에 놓임. 위치 전용 매개 변수를 나머지 매개 변수들로부터 논리적 분리하는데 사용. 위치 전용이면 매개변수 순서가 중요하고 키워드로 매개변수 전달 불가 +- 키워드 전용 인자 : 매개변수를 키워드 전용으로표시하기 위해 첫 번째 키워드 전용 매개 변수 바로 전에 인자 목록에 * 를 넣는다 + +```python +def standard_arg(arg): # 제한 X + print(arg) + +def pos_only_arg(arg, /): # 위치 전용 + print(arg) + +def kwd_only_arg(*, arg): # 키워드 전용 + print(arg) + +def combined_example(pos_only, /, standard, *, kwd_only): # 세 가지 호출 규칙 모두 사용 + print(pos_only, standard, kwd_only) +``` + +- 위치 인자 name과 name을 키로 가지는 **kwds 사이에 잠재적 충돌이 있는 경우를 고려 + +```python +def foo(name, **kwds): + return 'name' in kwds + +# foo(1,**{'name':2}) 호출 시 +# foo(name=1, name=2) +=> 같은 name에 두 번 값 전달 -> 에러 + +# 해결 : foo(name,/,**kwds): +``` + +- name 키워드는 항상 첫 번째 매개 변수에 결함하므로, True 반환 불가. ‘name’ 키가 **kwds로 절대 가지 못해서 항상 ‘name’ in kwds 가 False 라는 것 +- 위치 전용 인자 / 를 사용하여 해결 +- API의 경우 비호환 API 변경 발생 방지 위해 위치 전용 사용 지향 + + +**(4) 임의의 인자 목록** + +- 가변 위치 인자와 키워드 전용 인자 +- *args : 나머지 모든 위치 인자들 → 튜플로 형태로 args에 저장 +- **kwargs : 나머지 모든 키워드 인자들 → 딕셔너리 형태로 kwargs 에 저장 + +```python +def my_func(*args, **kwargs): + print("Positional arguments:") + for arg in args: + print(arg) + + print("\nKeyword arguments:") + for key, value in kwargs.items(): + print(f"{key}: {value}") + +# 위치 인자와 키워드 인자를 함께 사용하는 경우 +my_func(1, "apple", name="John", age=30) + +# 결과 +# Positional arguments: +# 1 +# apple + +# Keyword arguments: +# name: John +# age: 30 + +# 위치 인자만 사용하는 경우 +my_func("banana", "orange", "kiwi") + +# 결과 +# Positional arguments: +# banana +# orange +# kiwi + +# 키워드 인자만 사용하는 경우 +my_func(color="red", size="medium") + +# 결과 +# Positional arguments: + +# Keyword arguments: +# color: red +# size: medium +``` + + +**(5) 인자 목록 언 패킹** + +- 분리된 위치 인자들을 요구하는 함수 호출 시 언 패킹 해야하는 상황 발생 +- range() 함수는 start, stop 인자가 그 예 +- 리스트와 튜플로부터 인자 언패킹 위해 *연산자 사용 +- 딕셔너리는 ** 연산자 사용 + +```python +args = [3, 6] +list(range(*args)) # 리스트에서 언패킹된 인자로 호출 +[3, 4, 5] + +d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} +parrot(**d) +``` + + +**(6) 람다 표현식** + +- lambda 키워드를 통해 이름 없는 함수 만들 수 있음. 문법적으로 하나의 표현식으로 제한, 둘러싸는 스코프에 있는 변수들을 참조할 수 있음 + +```python +def make_incrementor(n): + return lambda x: x + n + +f = make_incrementor(42) +f(0) #42 +f(1) #43 +``` + +- list.sort() 에도 활용 + +```python +pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] +pairs.sort(key=lambda pair: pair[1]) +# pair[1] 을 기준으로 정렬하라 +``` + + +**(7) 도큐멘테이션 문자열 (독스트링)** + +- 첫 줄은 객체의 목적을 짧게, 간결 요약, 대문자 시작, 마침표 종료 +- 여러 줄이라면 두번 째 줄을 비워 요약과 설명을 분리 + +(8) 함수 어노테이션 + +- 함수 어노테이션 : 사용자 정의 함수가 사용하는 형들에 대한 선택적인 메타데이터 정보 +- f.__annotations__ 에 저장 +- -> : 반환 어노테션 + +```python +def f(ham: str, eggs: str = 'eggs') -> str: +# ham : str 기대 +# eggs : str 기대 +# -> : str 반환 기대 +``` + +참고 자료 +https://wikidocs.net/22799 +https://python101.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%ACPython%EC%9D%98-%EC%9E%84%EC%9D%98%EC%9D%98-%EC%9D%B8%EC%9E%90%EB%AA%A9%EB%A1%9Dvariadic-arguments-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C +https://wikidocs.net/22801 + From 239d7c51d2943d5b8d5387d9e53c08b61c5f6a63 Mon Sep 17 00:00:00 2001 From: erun1012 Date: Sun, 15 Feb 2026 15:04:50 +0900 Subject: [PATCH 3/3] add Unit5-9 --- Unit5-9/pythonic_unit5.md | 236 ++++++++++++++++++++++++++++++++++++++ Unit5-9/pythonic_unit6.md | 97 ++++++++++++++++ Unit5-9/pythonic_unit7.md | 86 ++++++++++++++ Unit5-9/pythonic_unit8.md | 191 ++++++++++++++++++++++++++++++ Unit5-9/pythonic_unit9.md | 149 ++++++++++++++++++++++++ 5 files changed, 759 insertions(+) create mode 100644 Unit5-9/pythonic_unit5.md create mode 100644 Unit5-9/pythonic_unit6.md create mode 100644 Unit5-9/pythonic_unit7.md create mode 100644 Unit5-9/pythonic_unit8.md create mode 100644 Unit5-9/pythonic_unit9.md diff --git a/Unit5-9/pythonic_unit5.md b/Unit5-9/pythonic_unit5.md new file mode 100644 index 0000000..c26e315 --- /dev/null +++ b/Unit5-9/pythonic_unit5.md @@ -0,0 +1,236 @@ +### 1. 리스트 더 보기 + +```python +list.append(x) # 리스트의 끝에 항목을 더함 +list.extend(iterable) # 리스트 끝에 이터러블의 모든 항목을 덧붙임 +list.insert(i,x) # 첫 번째 인자는 인덱스 주어진 인덱스 위치에 항목(x)을 삽입 +list.remove(x) # 리스트에서 값이 x와 같은 첫 번째 항목 제거 +list.pop([i]) # 리스트에서 주어진 위치의 항목 제거 후 돌려줌. 인덱스 없을 땐 마지막 항목을 삭제 +list.clear() # 리스트의 모든 항목 삭제 +list.index(x[,start[, end]]) # 선택적 인자 start와 end는 슬라이스 표기법 해석, 검색을 리스트의 특별한 서브 시퀀스로 제한하는데 사용 +list.count(x) # 리스트에서 x가 등장하는 횟수 +list.sort(*,key=None,reverse=False) # 리스트의 항목들을 제자리에서 정렬 +list.reverse() # 리스트의 요소들을 제자리에서 뒤집음 +list.copy() # 리스트의 사본 돌려줌 +``` + +- insert, remove, sort 같은 메서드들은 리스트를 수정, 반환 값 출력X. 기본 None을 돌려줌 ( 파이썬 모든 가변 자료 구조에 적용되는 설계 원리) +- 서로 다른 형 끼리는 비교할 수 없기에 정렬 등 불가능 + +```python +stack = [3,4,5] +stack.append(6) +stack.pop() +``` + +- 리스트를 스택으로 사용하기 + +```python +from collections import deque +queue=deque(["A","B","C"]) +queue.append("D") +queue.popleft() +``` + +- 리스트를 큐로 사용하기 + +```python +squares = [] +for x in range(10): + squares.append(x**2) + +squares = list(map(lambda x:x**2,range(10))) + +squares = [x**2 for in x in range(10)] +``` + +- 리스트 컴프리헨션 : 리스트를만드는 간결한 방법 제공. 다른 시퀀스나 이터러블 멤버에 연산을 적용한 결과 리스트를 만들거나 어떤 조건을 만족하는 요소들로 구성된 서브 시퀀스를 만드는 것. +- 리스트 컴프리헨션은 표현식과 for또는 if 절을 감싸는 대괄호로 구성. + +```python +vec = [-4, -2, 0, 2, 4] +# 값을 두배로 하여 새 리스트를 만듭니다 +[x*2 for x in vec] + +# 음수를 제외하도록 리스트를 필터링합니다 +[x for x in vec if x >= 0] + +# 모든 요소에 함수를 적용합니다 +[abs(x) for x in vec] + +# 각 요소에 메서드를 호출합니다 +freshfruit = [' banana', ' loganberry ', 'passion fruit '] +[weapon.strip() for weapon in freshfruit] + +# (숫자, 제곱) 과 같은 2-튜플의 리스트를 만듭니다 +[(x, x**2) for x in range(6)] + +# 튜플은 괄호로 묶어야합니다, 그렇지 않으면 에러가 발생합니다 +[x, x**2 for x in range(6)] + File "", line 1 + [x, x**2 for x in range(6)] + ^^^^^^^ +``` + +- 표현식이 튜플이면 반드시 괄호로 둘러싸야 함 + +```python +from math import pi +[str(round(pi,i)) for i in range(1,6)] + +matrix = [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], +] + +[[row[i] for row in matrix] for i in range(4)] + +# 복잡한 흐름문보다 내장 함수 선호 zip() 사용 가능 +list(zip(*matrix)) +``` + +- 복잡한 표현식과 중첩된 함수들 포함 가능 + +### 2. del 문 + +- 객체 자체를 삭제하는 키워드 + +```python +a=[1,2,3,4,5,6,7,8,9] +del a[0] # [2,3,4,5,6,7,8,9] +del a[2:4] # [2,3,6,7,8,9] +del a[:] # [] + +del a # 리스트 a를 비우는 것이 아닌 변수 이름 a 자체를 삭제 +``` + +| 구분 | del | pop() | +| --- | --- | --- | +| 삭제 기준 | 인덱스 | 인덱스 | +| 반환값 | X | 삭제한 값 반환 | +| 슬라이스 삭제 | 가능 | X | +| 변수 자체 삭제 | 가능 (del a) | X | + +### 3. 튜플과 시퀀스 + +- 시퀀스 자료형 : 리스트와 문자열 그리고 튜플 + +```python +t = 12345, 54321, 'hello!' + +# 튜플은 중첩될 수 있음 +u = t, (1, 2, 3, 4, 5) +u # ((12345, 54321, 'hello!'),(1, 2, 3, 4, 5)) + +# 튜플은 불변 +t[0] = 88888 # -> error + +# 하지만 가변 객체를 포함할 수 있음 +v = ([1, 2, 3], [3, 2, 1]) + +# 빈 튜플 +empty=() +# 하나의 항목으로 구성된 튜플은 값 뒤에 쉼표 붙여서 만듦 +singlton = 'hello', + +``` + +- 튜플은 항상 괄호에 둘러 쌓여 출력되지만 괄호 없이 입력될 수 있음. 튜플은 불변이고 언 패킹이나 인덱싱으로 액세스함. 그러나 리스트는 가변에 이터레이션으로 액세스 +- t = 12345,54321,’hello!’ 는 튜플 패킹의 예 +- x, y, z = t 는 시퀀스 언 패킹이라 불림. 좌변에시퀀스에 있는 요소들과 같은개수의 변수드링 올 것을 요구 + +### 4. 집합 + +- 중괄호나 set() 함수 사용 가능 + +```python +basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} +# 중복은 제거됨 + +'orange' in basket # True +'crabgrass' in basket # False + +# 두 단어의 고유한 글자들로 집합 연산 시연 + +a = set('abracadabra') +b = set('alacazam') + +a - b # a 에 있으나 b 에 없는 글자들 +a | b # a 나 b, 혹은 양쪽 모두에 있는 글자들 +a & b # a 와 b 모두에 있는 글자들 +a ^ b # a 나 b 에 있지만 양쪽 모두에 있지는 않은 글자들 + +a = {x for x in 'abracadabra' if x not in 'abc'} +# 집합 컴프리헨션도 지원 +``` + +- 빈 집합을 만드려면 set() + +### 5. 딕셔너리 + +- 키(key) : 값(value) +- 시퀀스 타입, 인덱스로 접근하는 리스트와 튜플과 다르게 딕셔너리는 키를 기반으로 접근하는 매핑 타입 +- key 는 반드시 불변 객체 (문자열, 숫자, 튜플(내용도 모두 불변인)) + +```python +d = {} # 빈 딕셔너리 + +d={"a":1,"a":2} # 키는 중복 불가능, 기존 값을 덮어씀 +-> {"a":2} + +d["name"]="철수" # 값 저장 +d["name"] # 값 가져오기 +del d["name"] # 삭제 + +dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) +# dict() 생성자는 키-값 쌍들의 시퀀스로부터 딕셔너리 구성 + +{x: x**2 for x in (2, 4, 6)} +# 딕셔너리 컴프리헨션 가능 +``` + +- 존재하지 않는 키 접근 시 keyError +- get() 으로 접근하면 에러가 아닌 None 출력 +- list(d) : 딕셔너리에 사용되고 있는 모든 리스트를 삽입 순서대로 돌려줌 +- sorted(d) : 정렬 +- 하나의 키가 딕셔너리에 있는지 검사하려면 in 키워드 + +### 6. 루프 테크닉 + +```python +knights = {'gallahad': 'the pure', 'robin': 'the brave'} +for k, v in knights.items(): + print(k, v) + +for i, v in enumerate(['tic', 'tac', 'toe']): + print(i, v) +``` + +- 딕셔너리로 루핑할 때, items() 메서드를 통해 대응하는 값을 얻을 수 있음 +- enumerate() 함수를 사용하면 위치 인덱스와 대응 값 얻을 수 있음 +- zip() 함수로 둘 이상의 시퀀스 동시 루핑 가능 +- reversed() 함수로 시퀀스 거꾸로 루핑 +- sorted() 함수로 정렬된 새 리스트 받기 +- set() 사용하면 중복 요소 제거 + +### 7. 조건 더 보기 + +- not 이 가장 높은 우선순위, or이 가장 낮은 우선순위 + - A and not B or C == (A and (not B)) or C +- 논리 연산자 and와 or 는 소위 단락 회로 연산자 + +### 8. 시퀀스와 다른 형들 비교하기 + +- 비교는 사전식 순서를 사용 +- 어느 한 시퀀스가 소진될 때까지 계속함 + +```python +(1, 2, 3) < (1, 2, 4) +[1, 2, 3] < [1, 2, 4] +'ABC' < 'C' < 'Pascal' < 'Python' +(1, 2, 3, 4) < (1, 2, 4) +(1, 2) < (1, 2, -1) +(1, 2, 3) == (1.0, 2.0, 3.0) +(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) +``` \ No newline at end of file diff --git a/Unit5-9/pythonic_unit6.md b/Unit5-9/pythonic_unit6.md new file mode 100644 index 0000000..206283a --- /dev/null +++ b/Unit5-9/pythonic_unit6.md @@ -0,0 +1,97 @@ +- 모듈 : 파이썬 정의와 문장들을 담고 있는 파일. 확장자 .py, 모듈의 이름은 전역변수 __name__으로 제공됨 +- 모듈 이름을 사용해 함수들을 액세스 할 수 있음 + +### 1. 모듈 더 보기 + +- 모듈은 함수 정의와 실행 가능한 문장들도 포함할 수 있다. 모듈을 초기화하는데 사용됨 +- 각 모듈은 자신만의 이름 공간을 가짐. 모듈에서 정의된 함수들의 전역 이름 공간으로 사용 +- 모듈은 다른 모듈을 import 할 수 있음 + + + +```python +from fibo import fib, fib2 +# 모듈에 들어있는 이름을 직접 import +from fibo import * +# 모듈이 정의하는 모든 이름을 import ( _ 로 시작하는 것들 제외) +from fibo as fib +fib.fib(500) +# 모듈 이름 다음에 as 가 올 때 as 다음의 이름을 임포트한 모듈에 직접 연결 +from fibo import fib as fibonacci +fibonacci(500) +# 위 처럼 쓰기도 함 +``` + +- 각 모듈은 인터프리터 세션마다 한 번만 임포트 됨. 모듈 수정 시 인터프리터 다시 시작해야함 + +- 모듈을 실행하면 모듈에 있는 코드는 그것을 임포트할 때 처럼 실행됨. __name__은 “__main__”로 설정 됨 + +```python +if __name__ == "__main__": + import sys + fib(int(sys.argv[1])) +``` + +- 위 코드를 모듈 끝에 붙여 스크립트로도 사용될 수 있도록 만들 수 있음 +- “메인” 파일로 실행될 때만 명령행을 파싱하는 코드가 실행되기 때문 + +- 모듈을 import 할 때 내장 모듈 → sys.path 순서대로 디렉터리를 검색 +- 스크립트 디렉터리가 가장 우선순위 높음 +- 같은 이름의 파일이 있으면 표준 라이브러리를 덮어 + +- 파이썬은 모듈 로딩 속도를 높이기 위해 컴파일된 바이트코드(.pyc)를 캐시함 __pycache__ +- 직접 실행한 파일과 소스 파일이 없는 pyc 경우 캐시 검사 안함 +- compileall 모듈 → 디렉터리 전체 .py 에 .pyc 미리 생성 + +### 2. 표준 모듈들 + +- 어떤 모듈들은 인터프리어테 내장됨 +- sys 모듈 + - sys.ps1와 sys.ps2는 기본과 보조 프롬프트로 사용되는 문자열을 정의함 + - sys.path 는 인터프리터의 모듈 검색 경로를 결정하는 문자열들의 리스트 + +### 3. dir() 함수 + +- 내장 함수, 모듈이 정의하는 이름들을 찾는 데 사용 + +```python +import fibo, sys +dir(fibo) +['__name__', 'fib', 'fib2'] +dir(sys) +['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', + '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', +... 생략...] + +# 인자가 없으면 dir()는 현재 정의한 이름들을 나열 +a = [1, 2, 3, 4, 5] +import fibo +fib = fibo.fib +dir() +['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys'] +``` + +- dir() 은 내장 함수와 변수들의 이름을 나열하지 않음 → 표준 모듈 builtins 에 정의 + +### 4. 패키지 + +- 점으로 구분된 모듈 이름, 모듈 이름 공간을 구조화 하는 방법 +- 파이썬이 디렉터리를 패키지 취급하게 만들기 위해서 __init__.py 파일이 필요하다. 이렇게하면 string 처럼 흔히 쓰는 이름의 디렉터리가 의도하지 않게 모듈검색 경로 뒤에 등장하는 올바른 모듈들을 가리는 일을 방지함 +- 패키지 사용자는 패키지로부터 개별 모듈을 import 할 수 있음 + +- import * : 시간이 오래 걸리고 서브 모듈을 import 함에 따라 원하지 않는 부수적 효과가 발생할 수 있음 + - 패키지 색인을 명시적으로 제공하는 것이 해결책 + - __init__.py 코드가 __all__이라는 이름의 목록을제공하면 import 해야만 하는 모듈 이름들의 목록으로 받아들임 +- 서브 모듈이 지역적으로 정의된 이름에 의해 가려질 수 있음( 지역적으로 정해진 함수 이름 같은거에 ) + +```python +from . import echo +from .. import formats +from ..filters import equalizer +``` + +- 패키지가 서브 패키지들로 구조화될 때 이웃 패키지의 서브 모듈을 가리키는데 절대임포트를 사용할 수 있음 + +- __path__ 이것은 패키지의 __init__.py파일을 실행하기 전에, 디렉터리 이름을 포함하는 문자열의 시퀀스로 초기화 됨 + - 패키지 import → 디렉터리 찾음 → 디렉터리.__path__ 생성 → 디렉터리.__init__.py 실행 +- 패키지에서 발견되는 모듈의 집합을 확장하는 데 사용 \ No newline at end of file diff --git a/Unit5-9/pythonic_unit7.md b/Unit5-9/pythonic_unit7.md new file mode 100644 index 0000000..717aa60 --- /dev/null +++ b/Unit5-9/pythonic_unit7.md @@ -0,0 +1,86 @@ +### 1. 장식적인 출력 포매팅 + +```python +f'Results of the {year} {event}' + +'{:-9} YES votes {:2.2%}'.format(yes_votes, percentage) +print('{0} and {1}'.format('spam', 'eggs')) +print('This {food} is {adjective}.'.format(food='spam', adjective='absolutely horrible')) + +table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} +print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ''Dcab: {0[Dcab]:d}'.format(table)) +print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)) + +print('The value of pi is approximately %5.3f.' % math.pi) +``` + +- 포맷 문자열 리터럴 : f 또는 F 를 붙여 문자열 시작, 문자열 안에서 {} 안에 변수 또는 리터럴 값을 참조할 수 있는 파이썬 표현식 작성 가능 + - 변수 뒤에 :정수 를 전달하면 해당 필드 최소 문자 폭 + - {} 속 변수에 수정자를 추가하면 포맷 전 값 변환 가능 + - !a : ascii() / !s : str() / !r : repr() + - {변수=} : 변수 = 변수 값 +- 문자열의 str.format() 메서드는 변수 대체 위치에 {}를 사용하고 자세한 포매팅 디렉티브 제공 가능, 포맷할 정보도 제공 + - 위치와 키워드 인자를 자유롭게 조합할 수 있음 + - [ ]를 통해 딕셔너리 키를 액세스할 수 있음 + - ** 표기법을 사용해 딕셔너리 인자 전달 가능 +- %연산 + +```python +s = 'Hello, world.' + +str(s) # Hello, world. +repr(s) # 'Hello, world.' +# 숫자, 리스트, 딕셔너리는 보통 동일 + +s = 'Hello, world.\n' +str(s) # 줄바꿈 적용 +repr(s) # 'Hello, world.\n' +``` + +- 수동 문자열 포매팅 + - str.rjust(x) : 우측 줄에 맞춤 + - str.ljust(x) + - str.center(x) + - str.zfill(x) : 숫자 문자열 왼쪽에 0을 채움 + +### 2. 파일 읽고 쓰기 + +```python +f = open(filename, mode, encoding=None) +``` + +- mode + - r : 읽기 + - w : 쓰기 + - a : 파일 덧붙이기 + - r+ : 읽고 쓰기 + - b를 추가 : 바이너리 모드, 데이터는 바이트 객체의 형태로 읽고 씀 + +```python +with open('workfile', encoding="utf-8") as f: + read_data = f.read() + +# 파일이 자동으로 닫혔는지 확인할 수 있습니다. +f.closed +``` + +- with 키워드를 사용하지 않으면 f.close() 를 호출해서 파일을 닫고 사용된 시스템 자원을 즉시 반납해야함 +- 파일 객체가 닫힌 후에는 wiht문이나 f.close() 를 호추하는 경우 모두, 파일 객체를 사용하려는 시도는 자동 실패 + +- f.read(size) : size가 없거나 음수면 내용 전체를 읽어서 돌려줌. +- f.readline() 은 파일에서 한 줄을 읽음. 개행문자 보존 +- list(f) or f.readlines() : 모든 줄을 리스트로 읽어들임 +- f.write(string) : string 내용을 파일에 쓰고 출력된 문자들의개수 돌려줌 +- f.tell() : 파일의 현재 위치를 가리키는 정수 돌려줌 +- f.seek(offset, whence) : 파일 객체의 위치 바꾸기. 기준점(whence)에서 offset을 더해서 계산. whence 기본값은 0 + +- json이라는 표준 모듈은 파이썬 데이터 계층을 받아서 문자열 표현으로 바꿔줌 ⇒ 직렬화 +- 문자열 표현으로부터 데이터를 재구성 하는 것 ⇒ 역 직렬화 + +```python +import json +x = [1, 'simple', 'list'] +json.dumps(x) # '[1, "simple", "list"]' +``` + +- dump() 라는 dumps() 함수의 변종, 객체를 텍스트 파일로 직렬화. \ No newline at end of file diff --git a/Unit5-9/pythonic_unit8.md b/Unit5-9/pythonic_unit8.md new file mode 100644 index 0000000..40e0758 --- /dev/null +++ b/Unit5-9/pythonic_unit8.md @@ -0,0 +1,191 @@ +### 1. 문법 에러(파싱 에러) + +- Syntax Error + +### 2. 예외 + +- 실행 중 감지되는 에러들을 예외라고 부름 +- 예외는 프로그램이 처리하지 않아서, 에러 메시지를 만듦 +- 예) ZeroDivisionError, NameError, TypeError (내장 예외들) + +### 3. 예외 처리하기 + +- 선택한 예외를 처리하는 프로그램 만들기 + +```python +while True: + try: + x = int(input("Please enter a number: ")) + break + except ValueError: # ValueError 에러가 오면 실행 + print("Oops! That was no valid number. Try again...") + except (RuntimeError, TypeError, NameError): # 튜플로 여러 개의 에외 지정 가능 + pass +``` + +- 각기 다른 예외에대한 처리기 지정을 위해 try 문은 하나 이상의 except 절을 가질 수 있음 + +```python +class B(Exception): + pass + +class C(B): + pass + +class D(C): + pass + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + except B: + print("B") +``` + +- except 절에 있는 클래스는 해당 클래스 자체나자식 클래스의 인스턴스인 예외와 매치됨 + +```python +try: + raise Exception('spam', 'eggs') +except Exception as inst: # 예외를 inst 로 받는다 + print(type(inst)) # 예외 + print(inst.args) # .args 에 저장된 인자들 + print(inst) # __str__ 는 args 가 직접 인쇄될 수 있게합니다, + # 하지만 예외 서브 클래스가 재정의할 수 있습니다 + x, y = inst.args # args 를 언팩합니다 + print('x =', x) + print('y =', y) +``` + +→ inst = Exception(’spam’,’eggs’) 이 객체를 받는 것과 같음 + +Exception 객체 +├─ args = ("spam", "eggs") +├─ __str__() +└─ __repr__() + +- 예외 클래스 계층 구조 + +BaseException +├─ Exception ← 우리가 일반적으로 다루는 예외 +├─ SystemExit +├─ KeyboardInterrupt +└─ GeneratorExit + +- BaseException에는 다양한 에러들이 포함되어 일반 예외만 잡기위해 Exception 을 잡아야함. +- 아래 코드가 가장 좋은 예외 처리 패턴 + +```python +try: + something() +except Exception as e: + print("Error:", e) + raise +``` + +- try … except 문은 선택적인 else 절을 가짐. 있다면 모든 except 절 뒤에 와야 함. try절이 예외를 일으키지 않을때만 실행될 때 유용 +- 예외 처리기는 try 절에서 호출되는 내부 함수들에서 발생하는 예외들도 처리 + +### 4. 예외 일으키기 + +- rasie 문 사용 +- raise 에 제공하는 단일 인자는 발생시킬 예외, + +### 5. 예외 연쇄 + +```python +try: + open("database.sqlite") +except OSError: + raise RuntimeError("unable to handle error") +``` + +→ open() 실패 → FileNotFoundError 발생 (OSError의 자식) → except OSError: 실행 → 그 안에서 새로운 예외 발생 + +- 첫 번째 예외를 처리하는 도중 두 번째 예외가 발생함 == 암묵적 예외 체이닝 - During handling…. +- 명시적 예외 체이닝 - direct cause +- rasie…from 을 쓰면 원인 관계를 명확히 지정 가능 + +- 예외 변환 : 낮은 레벨 예외 → 의미 있는 높은 레벨 예외 + +```python +def func(): + raise ConnectionError + +try: + func() +except ConnectionError as exc: + raise RuntimeError('Failed to open database') from exc +``` + +→ ConnectionError 발생 → except 에서 잡음 → RuntimeError로 변환 → from exc로 원인 해결 + +- raise —- from Nome : 기존 예외를 숨김. 체이닝 제거 + +- 기본체이닝 : __context__에 이전 예외 저장 +- raise … from exc : __cause__에 이전 예외 저장 +- raise … from Nome : __suppress_context__ = True + +### 6. 사용자 정의 예외 + +- 새 예외 클래스를만들어서 자신의 예외에 이름 붙일 수 있음 + +### 7. 뒷정리 동작 정의 + +- try 는 finally 절이있으면 try 문이 완료되기 전에 finally 절이 마지막 작업으로 실행됨. try 문이 예외 생성하는지와 관계 없이 실행되는 문장임 +- 예외 발생 시 finally 실행 후 예외 다시 발생 + +### 8. 미리 정의된 뒷정리 동작들 + +```python +with open("myfile.txt") as f: + for line in f: + print(line, end="") +``` + +- for 문이 아닌 with 문을 사용함으로써 문장이 실행된 후에, 줄을 처리하는 문제가 발생하더라도 파일 f 는 항상 닫힘. + + + +### 9. 여러 개의 서로 관련 없는 예외를 동시 처리 + +- 첫 번째 예외 발생으로 바로 종료 하면 안되니까 +- 동시성 상황 : 여러 개의 비동기 작업, 실패한 경우 모두 보고 +- 검증 상황 : 하나 고치고 다시 실행 보단 모든 오류 한 번에 보고 +- ExceptionGroup이 존재. + +```python +except* OSError as e: +# 그룹 전체 중 OSError만 분리해서 꺼낸 뒤 처리 + +ExceptionGroup("errors", [ValueError, TypeError]) # X +ExceptionGroup("errors", [ValueError(), TypeError()]) # O +``` + +- ExceptionGroup 안에는 예외 타입이 아닌 이미 발생한 예외 인스턴스가 들어가야함! +- 예외 타입에는 정보가 안 들어있기 때문에.. + +### 10. 예외에 추가 정보 덧붙이기 + +```python +raise TypeError("bad type") # 이런 식으로 메시지를 고정 + +try: + raise TypeError("bad type") +except Exception as e: + e.add_note("Add some information") + e.add_note("Add some more information") + raise + +# 출력 +TypeError: bad type +Add some information +Add some more information +``` + +- add_note() 를사용해 기존 traceback 유지하며 추가 가능 +- 새 예외를 raise 하면 traceback 손실, 원래 예외 타입 손실, 체이닝 복잡 등의 문제로 위 방법이 나음 \ No newline at end of file diff --git a/Unit5-9/pythonic_unit9.md b/Unit5-9/pythonic_unit9.md new file mode 100644 index 0000000..9fe1cd9 --- /dev/null +++ b/Unit5-9/pythonic_unit9.md @@ -0,0 +1,149 @@ +### 1. 이름과 객체 + +- 객체는 개체성, 여러 개의 이름이 같은 객체에 연결 가능 = 에일리어싱 +- 가변 객체를 수반할 때 에일리어싱이 극적 효과 줄 수 있음 + +### 2. 파이썬 스코프와 이름 공간 + +- 이름 공간 : 이름에서 객체로 가는 매핑 + - 대부분 현재 파이썬 딕셔너리로 구현 + - 서로 다른 이름 공간들의 이름 간에는 아무런 관계 X +- 어트리뷰트 : 점 뒤에 오는 모든 이름 + - 모듈에 있는 이름들에 대한 참조는 어트리뷰트 참조 + - 어트리뷰트는 읽기 전용, 쓰기 가능 + - 쓰기 가능한 어트리뷰트는 대입, del 삭제 모두 가능 +- 모듈의 전역 이름 공간은 모듈 정의를 읽는 동안 만들어짐 +- 모듈 이름 공간은 인터프리터가 끝날 때 까지 남음 +- 재귀적 호출은 각각 자기 자신만의 지역 이름 공간 가짐 +- 스코프 : 이름 공간을 직접 액세스할 수 있는 파이썬 프로그램의 텍스트적인 영역 +- 이름을 global로 선언하면 전역 이름 포함 스코프로 감 ↔ nonlocal +- 파이썬의 특징은 global 이나 nonlocal 문이 없을 때 이름에 대입하면 항상 가장 내부의 스코프에 감 + - del x 는 지역 스코프가 참조하는 이름 공간에서 x 의 연결을 제거함 + - global 문은 특정 변수가 전역 스코프에, 재연결되어야할 때 + - nonlocal 문은특정 변수가 둘러싸는 스코프에 있으며 재연결되어야 할 때 + + + +### 3. 클래스와의 첫 만남 + +- 클래스 정의 시 새 이름 공간 만들어지고 지역 스코프로 사용 +- 클래스 객체는두 종류의 연산을 지원 + - 어트리뷰트 참조 + - 인스턴스 만들기 : __init__(self) 메서드 정의, 새로 만들어진 클래스 인스턴스에 대해 자동 호출 +- 인스턴스 객체로는 어트리뷰트 참조가 가능 + - 데이터 어트리뷰트 + - 메서드 (객체에 속하는 함수) +- 메서드 객체와 함수 객체는 다름 + - 메서드는 데이터 어트리뷰트가 아닌 인스턴스 어트리뷰트를 참조하면그것의 클래스가 검색 됨 + - 이름이 함수 객체인 올바른 클래스 어트리뷰트면 인스턴스 객체와 함수 객체에 대한 참조가 함께 메서드 객체로 포장 + +- 인스턴스 변수 : 인스턴스별 데이터를 위한 것 +- 클래스 변수 : 그 클래스에서모든인스턴스에서 공유되는 어트리뷰트와 메서드를 위한 것 +- 가변 객체가 클래스 변수로 사용될 때 하나의 가변 객체가 모든 인스턴스들에 공유되기에 인스턴스 변수 사용해야 함 + +### 4. 기타 주의사항들 + +- 인스턴스와 클래스 모두에서 같은 어트리뷰트 이름이 등장하면, 어트리뷰트 조회는 인스턴스를 우선 +- 파이썬에서 데이터 은닉을 강제할 방법은 없다 +- 클래스 어트리뷰트인 모든 함수는 그 클래스의 인스턴스들을 위한 메서드를 정의 +- 메서드는 전역 이름을 참조할 수 있음. 메서드에 결합한 전역 스코프는 그것의 정의를 포함하는 모듈 + + + +### 5. 상속 + +```python +class DerivedClassName(BaseClassName): + + . + + +class DerivedClassName(modname.BaseClassName): +# 베이스 클래스가 다른 모듈에 정의되어 있을 때 +``` + +- 파생 클래스는 베이스 클래스의 메서드 재정의 가능 +- 파이썬에서 모든 메서드는 실질적으로 virtual 임 +- 상속과 함께 사용할 수 있는 내장함수 + - isinstance(obj, int) : 인스턴스 형을 검사, obj가 int 거나 int에서 파생됨 → True + - issubclass(obj, a) : 클래스 상속 검사, obj 가 a 의 서브 클래스면 True + +```python +class DerivedClassName(Base1, Base2, Base3): + + . + +``` + +- 다중상속, 상속된 어트리뷰트들의 검색을 깊이 우선으로, 왼쪽에서 오른쪽으로, 계층 구조에서 겹치는 같은 클래스를 두 번 검색하지 않는 것 +- 메서드 결정 순서 : super() 로의 협력적 호출 지원 위해 동적으로 변경 +- 동적 순서 : 다이아몬드 관계 해결 위함, 동적인 알고리즘이 검색순서를 선형화 함. 각 부모를 한 번만 호출, 단조적이게만듦 + + + +### 6. 비공개변수 + +- 파이썬에 객체내부에서만 액세스 가능한 비공개 인스턴스 변수는 없음 + +```python +class Mapping: + def __init__(self, iterable): + self.items_list = [] + self.__update(iterable) + + def update(self, iterable): + for item in iterable: + self.items_list.append(item) + + __update = update # 기존 update() 메서드의 비공개 사본 + +class MappingSubclass(Mapping): + + def update(self, keys, values): + # update() 에 새로운 서명을 제공하지만 + # __init__() 를 망가뜨리진 않습니다 + for item in zip(keys, values): + self.items_list.append(item) +``` + +- 서브 클래스에서 정의된 이름들과의 충돌을 막기 위해 이름 뒤섞기 메커니즘 지원 + - 최소 두 개의 밑줄 시작, 최대 한 개의 밑줄로 끝남 + + * exec(), eval()로 전달된 코드는 호출 클래스의 클래스 이름을 현재 클래스로 여기지 않음 - global 문의 효과와 유사 + +### 7. 잡동사니 + +- 몇몇 이름 붙은 데이터 항목들을 함께 묶어주는 struct 와 유사한 데이터형, dataclasses 를 사용하는 것이 일반적 + +```python +from dataclasses import dataclass + +@dataclass +class Employee: + name: str + dept: str + salary: int +``` + +### 8. 이터레이터 + +- for 문은 컨테이너 객체에 대해 iter()를 호출함. + - 이 함수는 메서드 __next__()를 정의하는 이터레이터 객체를 돌려줌 → 메서드는 컨테이너의 요소들을 한 번에하나씩 액세스 + - 남은 요소가 없으면 __next__()는 StopIteration 예외 발생 루프 종료 + +### 9. 제너레이터 + +- 이터레이터를 만드는 도구 +- 값을 돌려주고 싶을 때마다 yield 문 사용 +- 제너레이터에서 next()가 호출될 때마다 제너레이터는 떠난 곳에서 실행을 재개 (마지막 실행 문 기억) + +```python +def reverse(data): + for index in range(len(data)-1, -1, -1): + yield data[index] +``` + +### 10. 제너레이터 표현식 + +- 간단한 제너레이터는 리스트 컴프리헨션과 유사. 대괄호 대신 괄호 사용 +- 간결, 효율성 떨어짐, 리스트 컴프리헨션보다는 메모리 덜 씀 \ No newline at end of file