본문 바로가기

Python

Python에서 super() 함수의 이해

super()를 호출해서 리턴되는 임시객체는 클래스 메소드처럼 부모 클래스의 메소드만을 호출할 수 있도록 해주는 proxy 객체다. 이때 부모 클래스의 인스턴스는 생성되지 않는다.

부모 클래스의 인스턴스(a=Animal()했을 때 생성되는 a, 즉 인스턴스)와 super()를 호출했을 때 생성되는 임시객체는 다음과 같은 차이점이 있다.

 

  1. 임시객체는 super()로 호출된다. 즉, 자식 클래스를 정의한 코드 안에서만 반환하도록 되어있다.
    1. 내부적으로 파이썬이 method resolution order(MRO)를 구현하기 위해 사용된다,(MRO는 들어는 봤지만 아직 공부하지 않았기 때문에 찾아보도록 한다.)
  2. 클래스의 인스턴스는 인스턴스 메소드에 접근할수 있지만 임시객체는 클래스 그 자체(class Animal: 이라고 정의했을 때 생성되는 type의 인스턴스)의 메소드로만 사용할 수 있다.(@classmethod 데코레이터를 사용한 클래스 메소드처럼 활용된다.)
  3. 클래스의 인스턴스의 인스턴스 메소드는 그 인스턴스에 종속되어 있지만 임시객체의 메소드를 호출하면 자식 클래스의 인스턴스에 종속된다.
    아래의 코드에 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