super()를 호출해서 리턴되는 임시객체는 클래스 메소드처럼 부모 클래스의 메소드만을 호출할 수 있도록 해주는 proxy 객체다. 이때 부모 클래스의 인스턴스는 생성되지 않는다.
부모 클래스의 인스턴스(a=Animal()했을 때 생성되는 a, 즉 인스턴스)와 super()를 호출했을 때 생성되는 임시객체는 다음과 같은 차이점이 있다.
- 임시객체는 super()로 호출된다. 즉, 자식 클래스를 정의한 코드 안에서만 반환하도록 되어있다.
- 내부적으로 파이썬이 method resolution order(MRO)를 구현하기 위해 사용된다,(MRO는 들어는 봤지만 아직 공부하지 않았기 때문에 찾아보도록 한다.)
- 클래스의 인스턴스는 인스턴스 메소드에 접근할수 있지만 임시객체는 클래스 그 자체(class Animal: 이라고 정의했을 때 생성되는 type의 인스턴스)의 메소드로만 사용할 수 있다.(@classmethod 데코레이터를 사용한 클래스 메소드처럼 활용된다.)
- 클래스의 인스턴스의 인스턴스 메소드는 그 인스턴스에 종속되어 있지만 임시객체의 메소드를 호출하면 자식 클래스의 인스턴스에 종속된다.
아래의 코드에super().__init__(name)
를 호출하면 self.name은 Animal이 아니라 Dog의 인스턴스의 attribute가 된다.(애초에 super를 호출해도 Animal 클래스 그 자체(class Animal: def…로 정의한 것에 의해 생성된 type의 인스터스)의 임시객체가 생성되어 반환되는 거지 Animal의 인스턴스(a=Animal()했을 때 생성되는 a로 접근가능한 인스턴스)가 생성되는 게 아니니까 말이다.)
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
my_dog = Dog("Fido", "Labrador")
그리고 아래의 코드와 같이@classmethod데코레이터를 사용한 클래스 메소드의 경우, cls에는 class Animal def.. 라고 코드로 썼을 때 생성되는 type의 인스턴스가 인자로 전달되는데 이것은
위의 코드에 쓰여진 super().__init__(name)
했을 때 init(name) 했을때 부모클래스 그 자체가 전달되는 것과 같다.
class Animal:
def __init__(self, name):
self.name = name
def play(cls):
print("run")
Animal.play() # cls에 class Animal def.. 라고 코드로 썼을 때 생성되는 type의 인스턴스가 인자로 전달된다.
super()가 리턴하는 임시객체(proxy 객체) != a=Animal()로 생성되는 클래스의 인스턴스
super().init() 했을 때 부모클래스의 init의 self 파라미터에 인자로 전달되는 클래스 그 자체의 인스턴스(type의 인스턴스) != super()가 리턴하는 임시객체(proxy 객체)
a=Animal()로 생성되는 클래스의 인스턴스 != super().init() 했을 때 부모클래스의 init의 self 파라미터에 인자로 전달되는 클래스 그 자체의 인스턴스(type의 인스턴스)
a=Animal()로 생성되는 클래스의 인스턴스 != @classmethod데코레이터를 사용한 클래스 메소드를 호출했을때 cls 파라미터로 전달되는 클래스 그 자체의 인스턴스(type의 인스턴스)
super().init() 했을 때 부모클래스의 init의 self 파라미터에 인자로 전달되는 클래스 그 자체의 인스턴스(type의 인스턴스) == @classmethod데코레이터를 사용한 클래스 메소드를 호출했을때 cls 파라미터로 전달되는 클래스 그 자체의 인스턴스(type의 인스턴스)
로 정리된다.
Reference
https://docs.python.org/3/library/functions.html#super
https://docs.python.org/3/tutorial/classes.html
https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables
https://docs.python.org/3/library/functions.html#classmethod
https://docs.python.org/3/howto/descriptor.html
'Python' 카테고리의 다른 글
OOP - 주어진 문제 안에서 클래스를 식별하는 방법 (0) | 2023.07.02 |
---|---|
객체 지향 프로그래밍의 장점 (0) | 2023.07.01 |
객체 지향 프로그래밍이란 (0) | 2023.07.01 |
Faker seed를 사용해봤습니다 (0) | 2023.05.15 |