2016-08-23 2 views
2

Я прочитал кучу полезной информации о SO, а также статью в http://www.phyast.pitt.edu/~micheles/python/metatype.htmlКак создать класс singleton, который реализует абстрактный класс, не вступая в конфликт метакласса?

Однако, думаю, я все еще не нашел ответа. Отсюда новый вопрос.

Я создаю библиотеку функций/классов для собственного использования. В рамках этого я хотел бы создать класс Singleton. Любой другой класс должен унаследовать его и стать Синглтоном. Эти классы должны быть подклассифицированы.

Per SO пост в Creating a singleton in Python, я реализовал:

class _Singleton(type): 
    _instances = {} 
    def __call__(cls, *args, **kwargs): 
     if cls not in cls._instances: 
      cls._instances[cls] = super(
       _Singleton, cls).__call__(*args, **kwargs) 
     return cls._instances[cls] 


class Singleton(_Singleton('SingletonMeta', (object,), {})): 
    pass 

Он работает. Это помогает создать одноэлементный класс, который может быть подклассифицирован.

В моей библиотеке было бы несколько классов, которые бы реализовали абстрактный класс с использованием abc. Такой класс или класс, реализующий этот абстрактный класс, вероятно, может быть Singleton.

Так,

import abc 
class Foo(metaclass=abc.ABCMeta): 
    @abc.abstractmethod 
    def bar(self): pass 

class Bar(Singleton, Foo): # This generates the meta-class conflict 
    def bar(self): 
     return 'implemented' 
    def bat(self): 
     return 'something else' 

Ищу входов/помощь, чтобы помочь реализовать такой сценарий.

**

Резюме Требования:

**

  • механизм для создания класса Singleton.
  • Класс, реализованный как Singleton (через указанный механизм) должен быть подклассифицирован. В классе sub- у меня есть дополнительные/новые методы, чем базовый класс.
  • Механизм создания абстрактного класса (с помощью abc помогает).
  • Реализация этого абстрактного класса, который действует как Singleton. У
    могут быть дополнительные методы, чем сам абстрактный класс.

Любые вводы/помощь/указатели будут оценены.

С уважением

Шарада

+0

Если вы считаете, что требования противоречат друг другу, сообщите мне свои мысли о том, почему вы так думаете. Это будет высоко оценено. – Sharad

ответ

0

Вместо того, чтобы прибегать к метаклассу зарегистрировать свои одиночка, вы можете сделать это на базовый классе для иерархии - просто положить одноплодную логику методы __new__ вместо этого. Таким образом, вам не нужно менять метакласмент только из-за этого дополнительного поведения, и abc.metaclasses будут работать.

import abc 
class Foo(metaclass=abc.ABCMeta): 
    _singleton_registry = {} 
    def __new__(cls, *args, **kw): 
     if cls in in __class__._singleton_registry: 
      return __class__._singleton_registry[cls] 
     singleton = super().__new__(*args, **kw) 
     __class__._singleton_registry[cls] = singleton 
     return singleton 

    @abc.abstractmethod 
    def bar(self): pass