ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • __new__, __init__, __call__ Magic method 정리
    Today_I_Learned/Python 2021. 1. 15. 22:53

    셋 다 Class의 기본 함수들로, C나 C++의 생성자 역할을 한다고 보면 된다. 다만 상황에 따라 각각의 쓰임새가 다르다.

    먼저 Python3에서는 모든 Class가 Object class를 내부적으로 상속받도록 되어 있다. 그리고 Object Class가 __new__, __init__, __call__을 갖고 있기 때문에 이 세 함수를 override하는 것이 가능하다. Override하지 않으면 내부적으로 정의된 내용(object에서 정의된 내용)으로 자동 실행된다고 보면 된다.

    __new__

    실질적으로 객체를 생성하는 동작을 하는 함수로 객체 생성 시 자동으로 호출된다.

    static method (Class나 객체 모두를 통해 호출이 가능한 함수.)이므로 다음의 형태들 처럼 호출할 수 잇다.

    Class.__new__(obj), obj.__new__(), Class().__new__() -> 모두 가능

    첫번째 argument는 항상 해당 함수를 호출한 Class나 객체가 되며 보통 'cls'로 표기한다.(Class에 의해 호출될 일이 많으니까) 이외의 argument들은 *ars, **kwargs와 같은 형태로 전달 받을 수 있다.

    ex) def __new__(cls, *args, **kwargs)

    override할 때에는 반드시 객체를 생성하고 return해야 하는데, 이 때 객체를 생성하려면 결국 상위 class의 __new__를 호출하는 수밖에 없다. 따라서 직접 구현한 __new__ 함수 내부에는 super().__new__(cls)나 type.__new__(cls)와 같은 Code가 반드시 포함되어야 한다.

    __init__

    Class의 속성attribute(C나 C++에서 주로 멤버라 부르는 것들...)을 초기화 하는 함수.

    보통 Python에서 생성자라고 하면 거의 __init__을 염두하고 하는 말이다. 하지만 위에 적은 것처럼 실질적으로 객체를 만드는 동작은 __new__()가 담당한다.

    __new__와 마찬가지로 static method이며, Class가 객체를 생성할 때 자동으로 호출된다. (__new__실행 이 완료된 후 실행된다.)

    다만 __init__은 아무것도 return 할 수 없다. temp = Class.__init__()을 하면 temp는 None이 된다.

    __init__에 전달되는 argument들은 객체 생성 시 Class 이름 다음에 나오는 괄호 (...) 를 통해 전달된다.

    ex. apple = Fruit(color='red', shape='sphere') -> 'red', 'sphere'가 Fruit Class의 __init__으로 전달되는 argument들

    Class 상속의 상황에서, 자식 Class가 __init__을 override하게 되면 따로 부모 Class의 __init__을 호출하지 않는 이상, 부모 Class의 __init__은 사용되지 않는다.

    Python에서는 C 나 C++의 생성자가 역할에 따라 __new__와 __init__으로 나눠졌다고 볼 수 있다.

    __call__

    이 함수가 추가된 Class의 객체는 '호출 가능한' 속성을 갖게 된다.

    '호출가능한' 속성이란 callable이라고도 표현하며 ( )<ㅡ 괄호를 통해 어떤 대상을 실행할 수 있다는 것을 의미한다.

    __call__ 함수는 자식 Class로 상속되지 않는다.

    객체는 원래 objectEx( ) 와 같은 형태로 사용이 불가능하지만 Class에서 __call__ 함수를 override하면 호출 가능한 객체를 생성 할 수 있게 된다.

    class A: def __call__(self): pass a = A() a() // <- 이게 가능해짐. a.__dir__() //<- 여기에 '__call__'이 추가된다.

    Metaclass에서 __call__은 좀 더 의미가 있어지는데 다음 Link에서 잘 정리가 되어 있다.

    동작 원리는 같지만 Metaclass 개념이 더해지면서 헷갈리는 것일 뿐...

     

     

    https://alphahackerhan.tistory.com/34

    파이썬 메타클래스 쉽고 깊게 이해하기, Python Metaclass A to Z

    'Today_I_Learned > Python' 카테고리의 다른 글

    class method vs. static method  (0) 2023.09.26
    이터레이터 iterator  (0) 2023.09.17
    Python3 Scapy에 Read할 수 있는 Packet Header 추가하기(Scapy-2.4.3)  (0) 2021.02.15
    연산자 Overloading  (0) 2021.01.27
    Python3 locals()  (0) 2021.01.13

    댓글

Designed by Tistory.