싱글 톤을 만드는 방법을 배우고 있습니다. (제발, 여기서 싱글 톤이 좋지 않다고 생각하지 마십시오. 하나의 구현을 바탕으로 "장식 자 클래스"가 Python에서 작동하는 방법에 대한 설명이 필요합니다.
, 나는 다음과 같이 그 일을 시도 :class Singleton(object):
def __init__(self, klass):
print "S init"
self.klass = klass
self.instance = None
def __call__(self, *args, **kwargs):
print "S call"
if self.instance is None:
self.instance = self.klass(*args, **kwargs)
else:
self.instance(*args, **kwargs)
return self.instance
@Singleton
class KlasseA:
def __new__(cls, *args, **kwargs):
print "KA new"
def __init__(self, s):
print "KA init"
self.__init2(s)
def __call__(self, s=None):
print "KA call"
self.__init2(s)
def __init2(self, s):
if s: self.s = s
@Singleton
class KlasseB:
def __new__(cls, *args, **kwargs):
print "KB new"
def __init__(self, s):
print "KB init"
self.__init2(s)
def __call__(self, s=None):
print "KB call"
self.__init2(s)
def __init2(self, s):
if s: self.s = s
를 이제 같은 평 파일에 다음 줄을 추가하여 위의 테스트 :
print ""
a = KlasseA('one')
print "a -> ", id(a), a.s
b = KlasseA('two')
print "b -> ", id(b), b.s
print "a -> ", id(a), a.s
c = KlasseA()
print "c -> ", id(c), c.s
print "b -> ", id(b), b.s
print "a -> ", id(a), a.s
d = KlasseB('three')
print "d -> ", id(d), d.s
print "a -> ", id(a), a.s
내가있어 다음 :
S init
S init
S call
KA init
a -> 140525844905496 one
S call
KA call
b -> 140525844905496 two
a -> 140525844905496 two
S call
KA call
c -> 140525844905496 two
b -> 140525844905496 two
a -> 140525844905496 two
S call
KB init
d -> 140525844905568 three
a -> 140525844905496 two
따라서 싱글 톤 데코레이터가 실제로 작동합니다. 내가 여기에 이해가 안 무엇 :
- 나는 전화를 재정의 장식 생각, 그래서 전화
KlasseA()
효과적으로Singleton(KlasseA)()
를 호출합니다. 이로 인해KlasseA()
호출마다 새로운Singleton
인스턴스가 생성되지 않아야합니까? KlasseA
과KlasseB
의 선언 중에Singleton()
이 호출 되었기 때문에 "S init"라인이 두 개인 것으로 나타났습니다. 따라서Singleton
의 두 인스턴스가 생성되었습니다. 이 인스턴스들은 어디에 보관 되었습니까?위의 싱글 톤 데코레이터 레시피에는 '잡았다'가있을 수 있습니까?
아아아, 알 겠어! 그래서 (개념적으로) 클래스 자체의 정의를 재정의하고,'Singleton' 클래스의 인스턴스는'KlasseA'와'KlasseB'의 클래스 정의에 바인딩됩니다. – pepoluan
# 3의 경우, __call__을 래핑 된 클래스의''__call__' 메서드에 전달하면 안됩니까? 'else :'절을 삭제하면'b = KlasseA ('two')'는 더 이상'b.s' 속성에 영향을 미치지 않습니다. – pepoluan
글쎄, 수업을 어떻게 할 것인가에 달려 있습니다. 개념적으로,'Singleton .__ call__'은'a = KlasseA()'를 쓸 때 실제로'type .__ call__'의 롤을 채 웁니다; 그것은 함수처럼 클래스 이름이 사용되는 것을 의미하는 것을 결정하는 함수입니다. 반면에'KlasseA .__ call__'은'KlasseA'의 * 인스턴스 *가 함수처럼 사용되는 것을 결정하는 데 사용됩니다 :'a()'. – chepner