1. 재귀의 이해
재귀함수: 스스로를 호출하는 함수이다.
주요한 이유: 재귀함수를 모르면 못푸는 문제 유형들이 매우 중요하기 때문이다. 예) DFS, BFS, 트리순회(traversal)
def rec(n):
if n ==0:
return 0
else:
return n + rec(n-1)
print(rec(4)) # 4+3+2+1+0 = 10
def rec2(n):
if n<5:
print(n)
rec2(n+1)
rec2(1) # 1 2 3 4
유의사항 1: 모든 재귀함수는 반복문으로 치환 가능하다. 굳이 재귀를 쓰는 이유는 코드의 간결함과 직관성 때문이다.
유의사항 2: 재귀함수에는 반드시 종료조건이 있어야한다. 종료조건이 없으면 무한히 재귀호출하므로, 이를 막기 위해 오류가 발생한다.
RecursionError: maximum recursion depth exceeded while calling a Python object
print(sys.getrecursionlimit()) 을 통해 현재 정해진 최대 재귀 깊이 (maximum recursion depth)를 알 수 있다.
재귀로 접근해야하는 문제 알아채는법
문제푸는 전체과정을 볼때, 일부분을 푸는 과정이 전체를 푸는 과정과 유사할 경우 재귀함수를 사용한다.
예시:
1 부터 n까지의 자연수 총합 구하기, 팩토리얼 구하기, 피보나치
n! = n * (n-1)!
def factorial(n):
if n == 0:
return 1
return n*factorial(n-1)
fib[n] = fib[n-1]+fib[n-2], fib[1]=0, fib[2]=1
def fib(n):
if 2 >= n:
return n-1
return fib(n-1)+fib(n-2)
2. 클래스 심화
0. 상속 되짚기
Animal -> cat, dog
1. 메서드 오버라이딩
서브 클래스에서 상위클래스의 메서드를 재정의 하는 것을 의미한다. 이름은 같지만 다른 기능을 수행하고 싶을 때, 기능추가/수정 하고싶을 때 사용한다.
django에서의 오버라이딩
- 모델 클래스: save()를 오버라이딩해 저장전 에 특정 작업 수행
- 폼 클래스: clean()을 재정의해 유효성검사 리폼가능
- 뷰 클래스: dispatch()를 오버라이딩해...
즉 내장 메서드 쓰고는 싶은데 좀 바꾸고 싶을 때 쓰면 좋다
2. 추상 클래스
자체적으로 객체를 생성하지 않고 상속받는 하위클래스에서 반드시 구현해야하는 추상 메서드를 하나이상 가지고 있다. 즉 인터페이스/형태만 정의되어있다. 이런 추상 클래스를 이용해 인터페이스로서 활용할 수 있다. 또한 다형성을 이용하는 코드를 작성할 때 실수로 오버라이딩을 하지 않았을 때의 의도치 않은 동작을 방지할 수도 있다.
from abc import abstractmethod
class Shape:
@abstractmethod
def get_area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def get_area(self):
return 3.14*self.radius**2
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def get_area(self):
return self.width*self.height
장고에서는 BaseModel이 추상클래스에 해당한다. 이 BaseModel을 계층적으로 상속받으며 같은 이름의 메소드를 가지지만 실제 동작은 다른 여러 모델 객체들을 만들 수 있는 것이다.
'Python' 카테고리의 다른 글
객체지향 프로그래밍 (0) | 2023.05.01 |
---|---|
파이썬 패키지 관리 (0) | 2023.04.26 |
Asyncio, coroutine (0) | 2023.04.26 |
프로세스,스레드,멀티프로세싱, 멀티 스레딩 (0) | 2023.04.25 |
각 타입별 중요 메소드 (0) | 2023.04.24 |