복붙노트

[PYTHON] 싱글 톤을 정의하는 간단하고 우아한 방법이 있습니까? [복제]

PYTHON

싱글 톤을 정의하는 간단하고 우아한 방법이 있습니까? [복제]

파이썬에서 싱글 톤을 정의하는 많은 방법이있는 것처럼 보입니다. Stack Overflow에 대한 의견 일치가 있습니까?

해결법

  1. ==============================

    1.함수가있는 모듈 (클래스가 아닌)이 싱글 톤 (singleton)으로 잘 작동하기 때문에 필요성을 실제로 볼 수는 없습니다. 모든 변수는 모듈에 바인딩되며 어쨌든 반복적으로 인스턴스화 될 수 없습니다.

    함수가있는 모듈 (클래스가 아닌)이 싱글 톤 (singleton)으로 잘 작동하기 때문에 필요성을 실제로 볼 수는 없습니다. 모든 변수는 모듈에 바인딩되며 어쨌든 반복적으로 인스턴스화 될 수 없습니다.

    클래스를 사용하기를 원한다면 Python에서 개인 클래스 나 개인 생성자를 만들 수있는 방법이 없으므로 API를 사용하는 관행을 통하지 않고 여러 인스턴스화를 보호 할 수 없습니다. 나는 여전히 모듈에 메서드를 넣고 모듈을 싱글 톤으로 간주한다.

  2. ==============================

    2.내 독단의 구현은 다음과 같습니다. 수업을 꾸미기 만하면됩니다. 싱글 톤을 얻으려면 Instance 메서드를 사용해야합니다. 다음은 그 예입니다.

    내 독단의 구현은 다음과 같습니다. 수업을 꾸미기 만하면됩니다. 싱글 톤을 얻으려면 Instance 메서드를 사용해야합니다. 다음은 그 예입니다.

    @Singleton
    class Foo:
       def __init__(self):
           print 'Foo created'
    
    f = Foo() # Error, this isn't how you get the instance of a singleton
    
    f = Foo.instance() # Good. Being explicit is in line with the Python Zen
    g = Foo.instance() # Returns already created instance
    
    print f is g # True
    

    그리고 여기 코드가 있습니다 :

    class Singleton:
        """
        A non-thread-safe helper class to ease implementing singletons.
        This should be used as a decorator -- not a metaclass -- to the
        class that should be a singleton.
    
        The decorated class can define one `__init__` function that
        takes only the `self` argument. Also, the decorated class cannot be
        inherited from. Other than that, there are no restrictions that apply
        to the decorated class.
    
        To get the singleton instance, use the `instance` method. Trying
        to use `__call__` will result in a `TypeError` being raised.
    
        """
    
        def __init__(self, decorated):
            self._decorated = decorated
    
        def instance(self):
            """
            Returns the singleton instance. Upon its first call, it creates a
            new instance of the decorated class and calls its `__init__` method.
            On all subsequent calls, the already created instance is returned.
    
            """
            try:
                return self._instance
            except AttributeError:
                self._instance = self._decorated()
                return self._instance
    
        def __call__(self):
            raise TypeError('Singletons must be accessed through `instance()`.')
    
        def __instancecheck__(self, inst):
            return isinstance(inst, self._decorated)
    
  3. ==============================

    3.다음과 같이 __new__ 메쏘드를 오버라이드 할 수 있습니다 :

    다음과 같이 __new__ 메쏘드를 오버라이드 할 수 있습니다 :

    class Singleton(object):
        _instance = None
        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(
                                    cls, *args, **kwargs)
            return cls._instance
    
    
    if __name__ == '__main__':
        s1 = Singleton()
        s2 = Singleton()
        if (id(s1) == id(s2)):
            print "Same"
        else:
            print "Different"
    
  4. ==============================

    4.파이썬에서 싱글 톤을 구현하는 약간 다른 접근 방식은 Alex Martelli (Google 직원 및 Python 천재)의 borg 패턴입니다.

    파이썬에서 싱글 톤을 구현하는 약간 다른 접근 방식은 Alex Martelli (Google 직원 및 Python 천재)의 borg 패턴입니다.

    class Borg:
        __shared_state = {}
        def __init__(self):
            self.__dict__ = self.__shared_state
    

    따라서 모든 인스턴스가 동일한 ID를 갖도록 강요하는 대신 상태를 공유합니다.

  5. ==============================

    5.모듈 방식이 잘 작동합니다. 만약 내가 싱글 톤을 절대적으로 필요로한다면 메타 클래스 접근 방식을 선호한다.

    모듈 방식이 잘 작동합니다. 만약 내가 싱글 톤을 절대적으로 필요로한다면 메타 클래스 접근 방식을 선호한다.

    class Singleton(type):
        def __init__(cls, name, bases, dict):
            super(Singleton, cls).__init__(name, bases, dict)
            cls.instance = None 
    
        def __call__(cls,*args,**kw):
            if cls.instance is None:
                cls.instance = super(Singleton, cls).__call__(*args, **kw)
            return cls.instance
    
    class MyClass(object):
        __metaclass__ = Singleton
    
  6. ==============================

    6.데코레이터로 싱글 톤 패턴을 구현하여 PEP318에서이 구현을 참조하십시오.

    데코레이터로 싱글 톤 패턴을 구현하여 PEP318에서이 구현을 참조하십시오.

    def singleton(cls):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]
        return getinstance
    
    @singleton
    class MyClass:
        ...
    
  7. ==============================

    7.대답이 말하는 것처럼 가장 관용적 인 방법은 모듈을 사용하는 것입니다.

    대답이 말하는 것처럼 가장 관용적 인 방법은 모듈을 사용하는 것입니다.

    이를 염두에두고 여기에 개념 증명이 있습니다.

    def singleton(cls):
        obj = cls()
        # Always return the same object
        cls.__new__ = staticmethod(lambda cls: obj)
        # Disable __init__
        try:
            del cls.__init__
        except AttributeError:
            pass
        return cls
    

    __new__에 대한 자세한 내용은 Python 데이터 모델을 참조하십시오.

    예:

    @singleton
    class Duck(object):
        pass
    
    if Duck() is Duck():
        print "It works!"
    else:
        print "It doesn't work!"
    

    노트:

  8. ==============================

    8.한 번 파이썬에서 싱글 톤을 썼는데, 모든 멤버 함수에 classmethod 데코레이터가있는 클래스를 사용했습니다.

    한 번 파이썬에서 싱글 톤을 썼는데, 모든 멤버 함수에 classmethod 데코레이터가있는 클래스를 사용했습니다.

    class foo:
      x = 1
    
      @classmethod
      def increment(cls, y = 1):
        cls.x += y
    
  9. ==============================

    9.파이썬 문서는 이것을 다루고 있습니다 :

    파이썬 문서는 이것을 다루고 있습니다 :

    class Singleton(object):
        def __new__(cls, *args, **kwds):
            it = cls.__dict__.get("__it__")
            if it is not None:
                return it
            cls.__it__ = it = object.__new__(cls)
            it.init(*args, **kwds)
            return it
        def init(self, *args, **kwds):
            pass
    

    아마도 다음과 같이 보이도록 다시 작성합니다.

    class Singleton(object):
        """Use to create a singleton"""
        def __new__(cls, *args, **kwds):
            """
            >>> s = Singleton()
            >>> p = Singleton()
            >>> id(s) == id(p)
            True
            """
            self = "__self__"
            if not hasattr(cls, self):
                instance = object.__new__(cls)
                instance.init(*args, **kwds)
                setattr(cls, self, instance)
            return getattr(cls, self)
    
        def init(self, *args, **kwds):
            pass
    

    이것을 확장하려면 비교적 깨끗해야합니다.

    class Bus(Singleton):
        def init(self, label=None, *args, **kwds):
            self.label = label
            self.channels = [Channel("system"), Channel("app")]
            ...
    
  10. ==============================

    10.나는 이것에 대해 잘 모르지만, 프로젝트는 'Convention singletons'(강제 싱글 톤이 아닌)를 사용합니다. 즉, DataController라는 클래스가있는 경우 동일한 모듈에서이 클래스를 정의합니다.

    나는 이것에 대해 잘 모르지만, 프로젝트는 'Convention singletons'(강제 싱글 톤이 아닌)를 사용합니다. 즉, DataController라는 클래스가있는 경우 동일한 모듈에서이 클래스를 정의합니다.

    _data_controller = None
    def GetDataController():
        global _data_controller
        if _data_controller is None:
            _data_controller = DataController()
        return _data_controller
    

    완전한 6 행이기 때문에 우아하지 않습니다. 그러나 모든 내 싱글 톤은이 패턴을 사용하며 적어도 매우 명시 적입니다 (파이썬입니다).

  11. ==============================

    11.또한 싱글 톤이 왜 좋지 않은지와 안티 패턴인지에 대해 토론하는 흥미로운 기사가 ​​Google 테스팅 블로그에 있습니다.

    또한 싱글 톤이 왜 좋지 않은지와 안티 패턴인지에 대해 토론하는 흥미로운 기사가 ​​Google 테스팅 블로그에 있습니다.

  12. ==============================

    12.싱글 톤 데코레이터 (별명이라고도 함)를 만드는 것은 앞으로 클래스를 장식 (주석 달기)하려는 경우 우아한 방법입니다. 그런 다음 클래스 정의 앞에 @singleton을 넣으면됩니다.

    싱글 톤 데코레이터 (별명이라고도 함)를 만드는 것은 앞으로 클래스를 장식 (주석 달기)하려는 경우 우아한 방법입니다. 그런 다음 클래스 정의 앞에 @singleton을 넣으면됩니다.

    def singleton(cls):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]
        return getinstance
    
    @singleton
    class MyClass:
        ...
    
  13. ==============================

    13.다음은 Peter Norvig의 Python IAQ 예제입니다. Python에서 Singleton Pattern을 어떻게 수행합니까? (이 질문을 찾으려면 브라우저의 검색 기능을 사용해야하며, 직접 링크는 없습니다. 죄송합니다.)

    다음은 Peter Norvig의 Python IAQ 예제입니다. Python에서 Singleton Pattern을 어떻게 수행합니까? (이 질문을 찾으려면 브라우저의 검색 기능을 사용해야하며, 직접 링크는 없습니다. 죄송합니다.)

    또한 브루스 에켈 (Bruce Eckel)은 Thinking in Python (Thinking in Python)의 또 다른 예를 보여줍니다 (코드에는 직접 연결되어 있지 않습니다)

  14. ==============================

    14.나는 클래스 또는 인스턴스를 싱글 톤이되도록 강제하는 것은 과잉이라고 생각한다. 개인적으로, 나는 정상적인 인스턴스화 가능한 클래스, 준 개인 참조, 그리고 간단한 팩토리 함수를 정의하고 싶다.

    나는 클래스 또는 인스턴스를 싱글 톤이되도록 강제하는 것은 과잉이라고 생각한다. 개인적으로, 나는 정상적인 인스턴스화 가능한 클래스, 준 개인 참조, 그리고 간단한 팩토리 함수를 정의하고 싶다.

    class NothingSpecial:
        pass
    
    _the_one_and_only = None
    
    def TheOneAndOnly():
        global _the_one_and_only
        if not _the_one_and_only:
            _the_one_and_only = NothingSpecial()
        return _the_one_and_only
    

    또는 모듈을 처음 가져올 때 인스턴스화에 문제가없는 경우 :

    class NothingSpecial:
        pass
    
    THE_ONE_AND_ONLY = NothingSpecial()
    

    그렇게하면 부작용없이 새로운 인스턴스에 대한 테스트를 작성할 수 있으며 전역 명령문을 사용하여 모듈을 뿌릴 필요가 없습니다. 필요한 경우 나중에 변형을 파생시킬 수 있습니다.

  15. ==============================

    15.Singleton Pattern은 ActiveState로부터 Python으로 구현되었습니다.

    Singleton Pattern은 ActiveState로부터 Python으로 구현되었습니다.

    트릭은 다른 클래스 안에 하나의 인스턴스 만 있어야하는 클래스를 넣는 것입니다.

  16. ==============================

    16.좋아요, 싱글 톤은 선악 일 수 있습니다. 이것이 제가 구현 한 것입니다. 단순히 내부에 캐시를 도입하고 다른 유형의 여러 인스턴스 또는 동일한 유형의 많은 인스턴스를 생성하지만 다른 인수를 사용하는 고전적인 접근 방식을 확장합니다.

    좋아요, 싱글 톤은 선악 일 수 있습니다. 이것이 제가 구현 한 것입니다. 단순히 내부에 캐시를 도입하고 다른 유형의 여러 인스턴스 또는 동일한 유형의 많은 인스턴스를 생성하지만 다른 인수를 사용하는 고전적인 접근 방식을 확장합니다.

    비슷한 인스턴스를 함께 그룹화하고 동일한 인수를 사용하여 같은 클래스의 객체를 만들 수 없으므로 Singleton_group이라고 부릅니다.

    # Peppelinux's cached singleton
    class Singleton_group(object):
        __instances_args_dict = {}
        def __new__(cls, *args, **kwargs):
            if not cls.__instances_args_dict.get((cls.__name__, args, str(kwargs))):
                cls.__instances_args_dict[(cls.__name__, args, str(kwargs))] = super(Singleton_group, cls).__new__(cls, *args, **kwargs)
            return cls.__instances_args_dict.get((cls.__name__, args, str(kwargs)))
    
    
    # It's a dummy real world use example:
    class test(Singleton_group):
        def __init__(self, salute):
            self.salute = salute
    
    a = test('bye')
    b = test('hi')
    c = test('bye')
    d = test('hi')
    e = test('goodbye')
    f = test('goodbye')
    
    id(a)
    3070148780L
    
    id(b)
    3070148908L
    
    id(c)
    3070148780L
    
    b == d
    True
    
    
    b._Singleton_group__instances_args_dict
    
    {('test', ('bye',), '{}'): <__main__.test object at 0xb6fec0ac>,
     ('test', ('goodbye',), '{}'): <__main__.test object at 0xb6fec32c>,
     ('test', ('hi',), '{}'): <__main__.test object at 0xb6fec12c>}
    

    모든 객체는 싱글 톤 캐시를 가지고 있습니다 ... 이것은 악의가있을 수 있지만 어떤 경우에는 훌륭하게 작동합니다 :)

  17. ==============================

    17.

    class Singleton(object[,...]):
    
        staticVar1 = None
        staticVar2 = None
    
        def __init__(self):
            if self.__class__.staticVar1==None :
                # create class instance variable for instantiation of class
                # assign class instance variable values to class static variables
            else:
                # assign class static variable values to class instance variables
    
  18. ==============================

    18.함수 매개 변수의 기본값을 기반으로하는 내 간단한 솔루션입니다.

    함수 매개 변수의 기본값을 기반으로하는 내 간단한 솔루션입니다.

    def getSystemContext(contextObjList=[]):
        if len( contextObjList ) == 0:
            contextObjList.append( Context() )
            pass
        return contextObjList[0]
    
    class Context(object):
        # Anything you want here
    
  19. ==============================

    19.비교적 새로운 Python에 익숙하기 때문에 가장 일반적인 관용구가 무엇인지 모르겠지만 가장 간단한 것은 클래스 대신 모듈을 사용하는 것입니다. 클래스의 인스턴스 메소드는 모듈의 함수가되고 모든 데이터는 클래스의 멤버가 아닌 모듈의 변수가됩니다. 나는 이것이 사람들이 싱글 톤을 사용하는 문제의 유형을 해결하기위한 파이썬 적 접근이라고 생각한다.

    비교적 새로운 Python에 익숙하기 때문에 가장 일반적인 관용구가 무엇인지 모르겠지만 가장 간단한 것은 클래스 대신 모듈을 사용하는 것입니다. 클래스의 인스턴스 메소드는 모듈의 함수가되고 모든 데이터는 클래스의 멤버가 아닌 모듈의 변수가됩니다. 나는 이것이 사람들이 싱글 톤을 사용하는 문제의 유형을 해결하기위한 파이썬 적 접근이라고 생각한다.

    싱글 톤 클래스를 정말로 원한다면 "파이썬 싱글 톤"에 대한 Google의 첫 번째 히트에 설명 된 합리적인 구현이있다.

    class Singleton:
        __single = None
        def __init__( self ):
            if Singleton.__single:
                raise Singleton.__single
            Singleton.__single = self
    

    그 트릭을 할 것으로 보인다.

  20. ==============================

    20.싱글턴의 이복 형제

    싱글턴의 이복 형제

    나는 staale에 완전히 동의하고 여기서 singleton half brother를 만드는 샘플을 남긴다.

    class void:pass
    a = void();
    a.__class__ = Singleton
    

    a는 마치 싱글 톤과 같지 않더라도 싱글 톤과 동일한 클래스로보고합니다. 그래서 복잡한 클래스를 사용하는 싱글 톤은 우리가 그들에게 많은 것을 낭비하지 않는 것에 따라 끝납니다.

    그렇기 때문에 우리는 변수 나 모듈과 같은 효과를 내고 더 단순한 것을 사용할 수 있습니다. 여전히 명확한 클래스를 사용하고 파이썬에서 클래스가 객체이기 때문에 우리는 이미 객체를 가지고 있습니다 (객체가 아니라 인스턴스입니다).

    class Singleton:
        def __new__(cls): raise AssertionError # Singletons can't have instances
    

    인스턴스를 만들려고하면 좋은 어설 션 오류가 발생하고 정적 멤버를 파생 클래스에 저장하고 런타임에 변경 사항을 적용 할 수 있습니다 (저는 Python을 좋아합니다). 이 객체는 다른 형제들과 마찬가지로 (당신이 원한다면 여전히 만들 수 있습니다.) 그러나 단순성으로 인해 더 빠르게 실행되는 경향이 있습니다.

  21. ==============================

    21.

    class Singeltone(type):
        instances = dict()
    
        def __call__(cls, *args, **kwargs):
            if cls.__name__ not in Singeltone.instances:            
                Singeltone.instances[cls.__name__] = type.__call__(cls, *args, **kwargs)
            return Singeltone.instances[cls.__name__]
    
    
    class Test(object):
        __metaclass__ = Singeltone
    
    
    inst0 = Test()
    inst1 = Test()
    print(id(inst1) == id(inst0))
    
  22. ==============================

    22.위의 메타 클래스 기반 솔루션을 원하지 않고 간단한 함수 데코레이터 기반 접근 방식을 원하지 않는 경우 (예 : 싱글 톤 클래스의 정적 메서드가 작동하지 않기 때문에)이 절충안이 작동합니다.

    위의 메타 클래스 기반 솔루션을 원하지 않고 간단한 함수 데코레이터 기반 접근 방식을 원하지 않는 경우 (예 : 싱글 톤 클래스의 정적 메서드가 작동하지 않기 때문에)이 절충안이 작동합니다.

    class singleton(object):
      """Singleton decorator."""
    
      def __init__(self, cls):
          self.__dict__['cls'] = cls
    
      instances = {}
    
      def __call__(self):
          if self.cls not in self.instances:
              self.instances[self.cls] = self.cls()
          return self.instances[self.cls]
    
      def __getattr__(self, attr):
          return getattr(self.__dict__['cls'], attr)
    
      def __setattr__(self, attr, value):
          return setattr(self.__dict__['cls'], attr, value)
    
  23. from https://stackoverflow.com/questions/42558/python-and-the-singleton-pattern by cc-by-sa and MIT license