Можно ли наследовать одноэлементный класс Python? - PullRequest
3 голосов
/ 23 ноября 2011

Моя идея состоит в том, что любой из объектов должен существовать для всех подклассов класса Singleton.Код, который я пробовал, и матрица результатов приведены ниже.Матрица, кажется, работает нормально в случае подклассов.Я иду неправильным путем?Получило ли оно то, что происходит в случае объекта класса Parent и объекта подкласса?

Ответы [ 3 ]

3 голосов
/ 23 ноября 2011

Ни один из методов __new__() подклассов не имеет явного оператора return, поэтому все они возвращают None.Вот почему их новые экземпляры все одинаковы.С этим кодом они будут такими же, как Singleton():

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

class A(Singleton):
    def __new__(cls, *args, **kwargs):
        return super(A, cls).__new__(cls, *args, **kwargs)

class B(Singleton):
    def __new__(cls, *args, **kwargs):
        return super(B, cls).__new__(cls, *args, **kwargs)

class C(B):
    def __new__(cls, *args, **kwargs):
        return super(C, cls).__new__(cls, *args, **kwargs)

Нет необходимости определять __new__() для подклассов:

class A(Singleton):
    pass

class B(Singleton):
    pass

class C(B):
    pass
3 голосов
/ 23 ноября 2011

Код выглядит нормально, но не имеет смысла выбирать одно одноэлементное значение для общего доступа к классу и его подклассамСмысл подкласса в том, чтобы отличаться от родительского класса и от подклассов родного класса.Мне кажется странным, что у каждого класса нет своего отдельного экземпляра синглтона.

0 голосов
/ 25 октября 2015

Я решаю эту проблему с помощью абстрактных классов. По моему это выглядит так:

from abc import ABCMeta, abstractmethod


class BasicClass(object):
    __metaclass__ = ABCMeta

    instance = None

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super(BasicClass, cls).__new__(
                                    cls, *args, **kwargs)

        return cls.instance

    @abstractmethod
    def action(self):
        pass#do smthing


class FirstLevelChild(BasicClass):
    __metaclass__ = ABCMeta

    @abstractmethod
    def action(self):
        pass#do smthing in this or other abstract method
        # also pearent method can be called with help of super

class SecondLevelChild1(FirstLevelChild):
    def action(self):
        pass#do smthing unique for this class
        # in this or other abstract method
        # also pearent method can be called with help of super

class SecondLevelChild2(FirstLevelChild):
    def action(self):
        pass#do smthing unique for this class
        # in this or other abstract method
        # also pearent method can be called with help of super

Давайте проверим

>>> a1 = SecondLevelChild1()
>>> a2 = SecondLevelChild1()
>>> b1 = SecondLevelChild2()
>>> b2 = SecondLevelChild2()
>>> a1 == b1
False
>>> a1 ==a2
True
>>> b1 == b2
True
>>> 

ВНИМАНИЕ! Это решение поможет, если Вам нужно создавать экземпляры только дочерних классов последнего уровня. Вы не сможете создавать абстрактные классы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...