__new__, __init__사용
class A:
def __new__(self):
print('new')
def __init__(self, x):
print('init')
wa = A()
#new
print(wa)
#none
__new__
에서 인스턴스를 생성해 반환하지 않고 있으므로 __init__
이 실행되지 않았을 뿐더러 wa
는 None
이다.
오류 1.
__init__
에 인자 x를 주었을 때
class AA(metaclass=type): #metaclass 속성에 type 따로 넣는 것
def __new__(cls): #생성 관련 부분
print('new')
return super().__new__(cls)
def __init__(self, x): #초기값 주는 부분
print('init')
a = AA()
AA
의 인스턴스 a
를 만드는 부분에서 에러가 발생하였다.
new
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-293bd2c67928> in <cell line: 1>()
----> 1 a = AA()
TypeError: AA.__init__() missing 1 required positional argument: 'x'
__new__
의 동작 방식을 잘 몰랐기 때문에 왜 에러가 났는지 알 수 없었다.__new__
는 클래스 객체를 호출해 인스턴스화 할 떄 호출되며 그 반환값을 __init__
의 첫번째 인자인 self로 반환한다.
첫번째 예제에서는 None을 반환하였기 때문에 인스턴스가 생성되지 않았다.
오류 1에서는 자기자신을 super()
을 통해 type.__new__
의 인자로 전달하였기 때문에 __init__
이 호출되었다.
하지만 __init__
의 인자가 self
와 x
두개 필요하므로 에러가 발생한 것이다.
오류 2.
그렇다면 클래스AA
에 인자를 전달하며 인스턴스화를 진행한다면 어떻게 될까?
a = AA(1)
TypeError Traceback (most recent call last)
<ipython-input-6-c4b3379fea05> in <cell line: 1>()
----> 1 a = AA(1)
TypeError: AA.__new__() takes 1 positional argument but 2 were given
이번엔 __new__
에서 에러가 발생하는 것을 확인할 수 있다.__new__
는 인자를 하나만 받도록 되어있는데, cls
는 숨겨진 파라미터로 받아지기 때문에 두개의 인자가 들어왔다고 하는 에러가 뜬 것이다.
그래서
해결
class AA(metaclass=type): #metaclass 속성에 type 따로 넣는 것
def __new__(cls, x): #생성 관련 부분
print('new')
return super().__new__(cls)
def __init__(self, x): #초기값 주는 부분
print('init')
a = AA(1)
__new__
와 __init__
의 parameter 수를 맞추어 주고, 인스턴스 생성 시 argument를 넣어주니 오류가 나지 않았다.
이때 사용할 수 있는 것이 가변 포지셔닝, 가변 키워드 파라미터이다.
class AA(metaclass=type):
def __new__(cls, *args, **kwargs): #생성 관련 부분
print('new')
return super().__new__(cls)
def __init__(self, *args, **kwargs): #초기값 주는 부분
print('init')
a = AA(1)
a = AA()
#new
#init
이를 사용하면 어떤 argument를 넣어도 에러가 나지 않고 실행된다.
'고려대학교 지능정보 SW 아카데미 4기 > 정리노트' 카테고리의 다른 글
프로그래밍 심화 (5) - Python Class 클래스 (0) | 2024.03.11 |
---|