2022. 11. 11. 04:14ㆍ스파르타코딩(22.8.29~22.12.31)/TIL(Today I Learned)
- Today I Learned
- 이전 글에서 클래스형 APIVIEW에 대해 알아보았고
(Class)형의 상속의 특징과 장단점에 대해 알아보고자 한다.
- 클래스의 상속(Inheritance)이란
클래스의 '상속'이란,
기존에 정의 되어 있는 클래스에 정의 된 속성(필드와 메소드들)을 이어 받아,
그대로 사용하거나 수정 또는 다른 속성들을 추가하여 사용하는 것을 말한다.
기반 클래스를(기반 클래스 : 상속을 하고자하는 기반이 되는 클래스)
기초 클래스(base class)
부모 클래스(parent class)
상위 클래스(super class)라고 하며,
상속을 통해 새롭게 생성되는 클래스를
파생 클래스(derived class)
자식 클래스(child class)
하위 클래스(sub class)라고 한다.
- 상속의 기본 문법
이해를 위해 클래스명을 가족관계로 표현했다.
- class 상속을 받을 자식클래스(상속시켜줄 부모 클래스)
- 자식 클래스에서 부모클래스를 호출하는 2가지 방법
상위 클래스의 메소드는 클래스 이름과 super()를 통해 호출 될 수 있다.
- 상속과 __init__ 메소드
파이썬에서 상속을 하면
자식 클래스의 __init__() 메소드에 <<< 부모 클래스의 __init__() 메소드를
명시적으로 호출해주어야 한다.
호출방법은 위에서 클래스도 가능하지만 , super()가 '항상' 권장된다.
자식클래스에 son attribute(속성)이 없다고 한다. 자식 클래스의 __init__() 메소드에
부모 클래스의 __init__() 메소드를 명시적으로 호출
정상적으로 작동한다.
- 다중 상속과 MRO (Method Resoultion Order)
파이썬은 여러개의 클래스로 부터 동시에 상속 받는 '다중 상속'을 지원한다.
다중 상속 : 여러 개의 기반 클래스로 부터 동시에 모든 속성들을 물려 받는 받는 것을 말한다.
Q.부모클래스 Father,Mother 클래스 모두가 같은 메소드를 가지고 있다면 상속을 받은
자식클래스 Son 클래스에서 호출하는 gift() 메소드는 어느 클래스에서 상속 받은 gift() 메소드일까?
A.메소드명이 같을 경우 먼저 상속 받은 클래스의 것을 사용한다.
만일 SON(Mother,Father)의 경우는 Mother의 gift를 사용하게 된다.
이렇게 어떤 메소드를 사용할지 순서를 결정하는 것을
MRO(Method Resolution Order)라고 한다.
Method : 메소드
Resolution : 결정,해결
Order : 순서
직역하면 "메소드 결정 순서"라고 한다.
클래스의 순서를 알아보기 위해 "클래스이름.mro()를 사용 할 수 있다.
다중상속의 순서를 알아보기 위해 위의 프린트문의 출력 예시
클래스 Son은 Father > Mother > object (시스템에서 지정하는 최상위 클래스) 순서라고 나온다.
Q. 객체 a를 이용하여 Mather의 gift 함수를 출력 하려면 상속 순서를 변경하는것 어떤 방법이 있을까A. 아래와 같이 super()를 사용하면 된다.
호출결과 Father의 gift를 요청했는데 Mother gift가 나온다...??
Super(타입,객체).메소드()
super 함수는 MRO 순서에서 타입으로 지정된 클래스의 '다음'순서의 클래스를 리턴한다.
정책에 맞춰 올바르게 Father에 해당하는 값을 출력하려면 아래와 같다.
위에서 MRO를 확인한 결과 SON > FATHER > MOTHER 순으로 나오며,
즉 super(Son, a)은 a의 객체를 자기자신으로 보고 Son의 다음 순서 즉 Father.gift를 호출하게 된다.
Mother의 gift를 가져올경우
super(Father,a).gift()가 되는것이다.
- 다이아몬드 상속과 super()
하나(A)의 기반 클래스에서 두 개(B,C)의 클래스가 상속 받고,
그 두개의 클래스를 다중 상속 받는 클래스(D)가 있다면
이것은 다이아몬드 상속이라고 한다.
mro순서 Son > Son의 상속배열의 순서인 Father > Mother > contributor(기부자)
위 구조에서 클래스 SON의 객체를 생성하면, SON은 Father,Mother 두개의 클래스 부터 다중 상속을 받고 있으므로,
__init__()에서 각 기반 클래스들의 __init__() 메소드를 명시적으로 호출하고 있다.
다시
Father는 __init__()이 contributor __init__()을 호출하고
Mother는 __init__()도 contributor __init__()을 호출하게되어
contributor는 두번을 호출 받게된다.
기반클래스의 __init__()을 직접 호출하게 되면 이러한 문제가 발생한다.
이런 문제는 위에서 다뤘던 super()를 사용하면 깔끔히 해결된다.
super()에 아무런 인자를 넘겨주지 않으면 파이썬에는 다음과 같은 디폴트 인자를 사용한다.super(self.__class__, self)이것은 자신의 클래스 이름과 self 객체를 인자로 넘기는 것이다.이렇게 되면 MRO 순서에 따라SON의 super는 Father이며,Father의 super는 MotherMother의 super는 contributor가 되어 각각 __init__이 한번씩만 호출 된다.
이렇게 super()하는 것은 중요하다. 이해가 안된다고 하더라도 상위 클래스의 메소드를 호출 할 때는
무조건 super를 이용해야 한다고 기억해두자.
https://kukuta.tistory.com/337님의 글을 발췌
이처럼 상속은 간단하지만 init이 중첩되지 않도록 사용방법에 유의하여 super를 활용해야한다.
이제 DRF의 APIVIEW에서의 예시를 보자
상속을 받지 않고 한다면 Permission을 위와 같이 커스텀 하듯이 해야 할 것이다.
하지만 DRF는 해당 기능을 APIVIEW에 추가를 함으로서 상속을 통해 가볍게 사용할 수 있다.
물론 예시와 같이 커스텀이 필요하다면 커스텀모델을 통해 위와같이 수정해야한다.
앞으로는 상속을 활용해 DRF의 여러 기능을 가볍게 사용해보자
결론 : APIVIEW에 대해 질의를 하다 Permission과 상속 특징에 대해 얘기가 나왔는데
알아보고자 했던 내용이 생각보다 깊어진것 같다..
상속개념을 복습하며 __init__과 super에 대해 다시한번 알게되었다.
물론 DRF의 여러 기능들은 __init__이 포함되어있어 그냥 사용하면 되는걸로 보인다.
장고를 다루며 여러 API를 다룰텐데 상속 개념을 알고 간것에 만족한다.
참조 및 발췌: APIView에 permission 지정하기
참조 및 발췌: 클래스의 상속이란? https://kukuta.tistory.com/337
'스파르타코딩(22.8.29~22.12.31) > TIL(Today I Learned)' 카테고리의 다른 글
[TIL] django.db.models.Model에 관하여 11/10 9일차 (0) | 2022.11.13 |
---|---|
[TIL] ORM과 객체,Class,instance에 대해 11/9 8일차 (0) | 2022.11.13 |
[TIL] API,VIEW / DRF의 api_view , APIVIEW 11/07 6일차 (0) | 2022.11.10 |
[TIL] DRF Class Based View 클래스형 CBV 11/04 5일차 [2/2] (0) | 2022.11.04 |
[TIL] API 자동화 문서 말 그대로 멋진 SWAGGER 11/04 05일차 [1/2] (0) | 2022.11.04 |