关于继承:两个单例子类是否有可能在Python中使用自己的超类实例?

Is it possible for two singleton subclasses to use their own instance of superclass in Python?

我有两个单例子类A和B,需要分别维护这些数据。当一个子类a使用超类时,其中一些信息将存储在列表中,而dict则存储在超类中。但当我试图从另一个子类B调用超类时,由子类A存储的信息会引起问题。

是否可以为A和B子类同时拥有超类的单独实例?

(我用自己作为超类成员)


我不确定我是否完全理解您的问题,部分原因是您的问题中没有包含任何代码。因此,仅根据我对您所写描述的解释,我认为下面将讨论两个单例子类相互干扰的问题。

一般的singleton元类用于定义基本的singleton类。元类确保为其自身的每个单例类实例(即本例中的MySingletonBase)创建单独的单例,这正是我认为您想要的。从它派生的两个子类,AB将从基类继承这个元类,因此将具有其单个子类的独立实例。

下面的代码基于我对问题的回答之一:&如何初始化一次单例派生对象?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# singleton metaclass
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 MySingletonBase(object):
    __metaclass__ = Singleton
    def __init__(self):
        self.values_list = []
    def test_method(self, value):
        self.values_list.append(value)
    def total(self):
        return sum(self.values_list)

class A(MySingletonBase): pass

class B(MySingletonBase): pass

a1 = A()
b1 = B()
a2 = A()

a1.test_method(42)
a2.test_method(13)
print '{}, {}'.format(a1.values_list, a1.total())  # [42, 13], 55
print '{}, {}'.format(a2.values_list, a2.total())  # [42, 13], 55
print '{}, {}'.format(b1.values_list, b1.total())  # [], 0

输出表明,子类A的实例确实是单例的,与子类B创建的任何实例都是分离的,但它们都继承MySingletonBase的方法。


基类的数据成员不在Python中共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base(object):
    def __init__(self, x):
        self.x = x

class Derived1(Base):
    def __init__(self, x, y):
        Base.__init__(self, x)
        self.y = y

class Derived2(Base):
    def __init__(self, x, z):
        Base.__init__(self, x)
        self.z = z

d1 = Derived1(10, 20)
d2 = Derived2(30, 40)
print d1.x   # Will show 10
print d2.x   # Will show 30

你所观察到的问题可能与其他事情有关。


谢谢你的回复,

我犯的错误是我宣布基地组织成员名单1的位置不对,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class BaseClass(metaclass=Singleton):
    list1 = []
    def __init__(self, a, b, c):
        self.list1.extend([a,b,c])

    def printList(self):
        print(self.list1)

class SubClass1(BaseClass):
    def __init__(self):
        super(SubClass1, self).__init__('a', 'b', 'c')

class SubClass2(BaseClass):
    def __init__(self):
        super(SubClass2, self).__init__('x','y','z')

if '__main__' == __name__:

    s1 = SubClass1()
    s2 = SubClass2()
    s1.printList()
    s2.printList()

这个问题已经解决了,我在init方法中声明了list1之后

1
2
3
4
class BaseClass(metaclass=Singleton):
    def __init__(self, a, b, c):
        self.list1 = []
        self.list1.extend([a,b,c])