가장 잘 알려진 OO 언어에서와 같은 표현식 SomeClass(arg1, arg2)
은 새 인스턴스를 할당하고 인스턴스의 속성을 초기화 한 다음 반환합니다.
가장 잘 알려진 OO 언어에서 "인스턴스 속성 초기화"부분 은 기본적으로 새 인스턴스에서 작동하는 코드 블록 (생성자 표현식에 제공된 인수를 사용하여) 인 생성자 를 정의하여 각 클래스에 대해 사용자 정의 할 수 있습니다. )를 사용하여 원하는 초기 조건을 설정하십시오. 파이썬에서 이것은 클래스의 __init__
메소드에 해당합니다 .
파이썬 __new__
은 "새 인스턴스 할당"부분의 비슷한 클래스 별 사용자 정의에 지나지 않습니다. 물론 새 인스턴스를 할당하는 대신 기존 인스턴스를 반환하는 등의 비정상적인 작업을 수행 할 수 있습니다. 파이썬에서 우리는이 부분이 반드시 할당과 관련이 있다고 생각해서는 안됩니다. 우리가 필요로하는 것은 __new__
어딘가에서 적합한 인스턴스를 만들어 내는 것입니다.
그러나 그것은 여전히 작업의 절반에 불과하며, 파이썬 시스템이 때로는 작업의 다른 절반을 실행하고 싶을 때가 있다는 것을 알 __init__
수있는 방법이 없습니다. 당신이 그 행동을 원한다면, 당신은 그렇게 분명하게 말해야합니다.
종종 리팩토링하여 필요 __new__
하거나 필요하지 않거나 이미 초기화 된 객체에서 다르게 동작 __new__
하도록 할 수 __init__
있습니다. 당신이 정말로, 파이썬은 실제로 수 있습니까하려는 경우 그이 있도록하지만, "작업"을 다시 정의 할 SomeClass(arg1, arg2)
필요는 호출하지 않습니다 __new__
다음에 __init__
. 이렇게하려면 메타 클래스를 작성하고 해당 __call__
메소드를 정의해야 합니다.
메타 클래스는 클래스의 클래스 일뿐입니다. 그리고 클래스의 __call__
메소드는 클래스의 인스턴스를 호출 할 때 발생하는 일을 제어합니다. 따라서 metaclass ' __call__
메소드는 클래스를 호출 할 때 발생하는 상황을 제어합니다. 즉 , 인스턴스 생성 메커니즘을 처음부터 끝까지 재정의 할 수 있습니다 . 싱글 톤 패턴과 같은 완전히 비표준 인스턴스 생성 프로세스를 가장 우아하게 구현할 수있는 수준입니다. 사실, 코드의 10 개 라인 당신이 구현할 수있는 Singleton
다음도 futz에 당신을 필요로하지 않는 메타 클래스를 __new__
전혀 하고 설정할 수 있는 간단하게 추가하여 싱글로, 그렇지 않으면 정상 수업을 __metaclass__ = Singleton
!
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
그러나 이것은 아마도이 상황에서 보장되는 것보다 더 깊은 마법 일 것입니다!