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

时间:2013-09-13 17:33:00

标签: python inheritance

我有两个单独的子类A和B,这些数据需要单独维护。当一个子类A使用超类时,一些信息将存储在列表中并且dict存储在超类中。但是当我尝试从另一个子类B调用超类时,子类A存储的信息会导致问题。

是否可以为A和B子类分别设置超类实例。

(我使用self作为超类成员)

3 个答案:

答案 0 :(得分:1)

基类的数据成员在Python

共享
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)

我不确定我是否完全理解您的问题,部分原因是您未在问题中包含任何代码。因此,仅基于我对您所编写的描述的解释,我认为以下内容将解决两个单例子类相互干扰的问题。

通用的Singleton 元类用于定义基本单例类。元类确保为每个单独的类实例创建一个单独的单个实例 - 即在这种情况下你的MySingletonBase - 这正是我想你想要的。从它派生的两个子类AB将从基类继承此元类,从而将具有其单例超类的独立实例。

以下代码基于我对该问题的一个回答:
How to initialize Singleton-derived object once?

# 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的方法。

答案 2 :(得分:0)

感谢您的回复,

我犯的错误是我在错误的地方声明了基类成员list1,

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之后,问题已经解决了。

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