문제

객체에 멤버가 있는지 정기적으로 확인하고 싶습니다. 예를 들어 함수에서 싱글 톤을 만드는 것입니다. 그 목적을 위해 사용할 수 있습니다 hasattr 이와 같이:

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance

그러나 당신은 또한 이것을 할 수 있습니다 :

class Foo(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Foo()
            return self.instance

한 방법이 다른 방법보다 더 나은 방법입니까?

편집하다: 추가 @classmethod ... 그러나 질문은입니다 ~ 아니다 싱글 톤을 만드는 방법에 대해서는 물체에 멤버의 존재를 확인하는 방법에 대해.

편집하다: 이 예를 들어, 일반적인 사용법은 다음과 같습니다.

s = Foo.singleton()

그 다음에 s 유형의 대상입니다 Foo, 매번 동일합니다. 그리고 일반적 으로이 방법을 여러 번이라고합니다.

도움이 되었습니까?

해결책

이것들은 두 가지 다른 방법론입니다.

Pythonistas는 일반적으로 EAFP가 더 좋다고 제안합니다. 이 주장은 여기에는 적용되지 않지만 일반적인 아이디어입니다. 예외는 다음과 같이 취급되어서는 안됩니다 ~도 특별한.

귀하의 경우 성능 측면-예외 관리자를 설정하는 경우 ( try 키워드)는 예외를 생성하면서 Cpython에서 매우 저렴합니다 ( raise 키워드 및 내부 예외 생성))는 비교적 비싸다. 그 후에는 속성을 사용합니다.

다른 팁

방금 시간을 측정하려고 노력했습니다.

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance



class Bar(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Bar()
            return self.instance



from time import time

n = 1000000
foo = [Foo() for i in xrange(0,n)]
bar = [Bar() for i in xrange(0,n)]

print "Objs created."
print


for times in xrange(1,4):
    t = time()
    for d in foo: d.singleton()
    print "#%d Foo pass in %f" % (times, time()-t)

    t = time()
    for d in bar: d.singleton()
    print "#%d Bar pass in %f" % (times, time()-t)

    print

내 기계에서 :

Objs created.

#1 Foo pass in 1.719000
#1 Bar pass in 1.140000

#2 Foo pass in 1.750000
#2 Bar pass in 1.187000

#3 Foo pass in 1.797000
#3 Bar pass in 1.203000

시도/을 제외하고는 더 빠른 것 같습니다. 어쨌든이 테스트는 더 복잡한 테스트가 필요할 것입니다.

예외는 비정형 조건을 모델링해야하기 때문에 어떤 경우가 "일반적인"경우에 따라 다릅니다. 따라서 일반적인 경우는 instance 속성이 존재하고 두 번째 코드 스타일을 사용해야합니다. 없는 경우 instance 전형적인 것만 큼 일반적입니다 instance, 그런 다음 첫 번째 스타일을 사용하십시오.

싱글 톤을 만드는 특정 사례에서는 첫 번째 스타일을 사용하는 경향이 있습니다. 싱글 톤을 만드는 것은 일반적인 사용 사례이기 때문입니다. :-)

그것을 사용하는 방식에 약간의 주제. 싱글 톤은 과대 평가되며 "공유 상태"방법은 예를 들어 파이썬에서 효과적이며 대부분 매우 깨끗합니다.

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # and whatever else you want in your class -- that's all!

이제마다 당신이 할 때마다 :

obj = Borg()

정보가 동일한 정보를 가지고 있거나 다소 동일한 인스턴스가됩니다.

크리스와 동의해야합니다. 실제로 그렇게해야 할 때까지 최적화하지 마십시오. 나는 존재하는 것이 합리적인 프로그램에서 병목 현상이 될 것이라고 정말로 의심합니다.

나는 보았다 http://code.activestate.com/recipes/52558/ 이를 수행하는 방법으로도. 해당 코드의 무의미한 사본 ( "스팸"은 클래스 인터페이스가 가진 임의의 메소드입니다).

class Singleton:
    class __impl:
        def spam(self):
            return id(self)
    __instance = None
    def __init__(self):
        if Singleton.__instance is None:
            Singleton.__instance = Singleton.__impl()
        self.__dict__['_Singleton__instance'] = Singleton.__instance
    def __getattr__(self, attr):
        return getattr(self.__instance, attr)
    def __setattr__(self, attr, value):
        return setattr(self.__instance, attr, value)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top