如何从父类扩展列表?

4 投票
4 回答
1199 浏览
提问于 2025-04-28 03:06

我有以下代码。父类有一个物品列表,子类需要在这个列表上添加内容。

每个父类的实例都需要有这个列表,而每个子类则需要有这个列表加上额外的值。

class Parent(object):
    a_list = ['parent_item1', 'parent_item2', ]

    def print_list(self):
        print(self.a_list)


class Child1(Parent):
    def __init__(self, *args, **kwargs):
        super(Child1, self).__init__(*args, **kwargs)
        self.a_list += ['child1_item']


class Child2(Parent):
    def __init__(self, *args, **kwargs):
        super(Child2, self).__init__(*args, **kwargs)
        self.a_list += ['child2_item']


parent = Parent()
child1 = Child1()
child2 = Child2()

parent.print_list()
    # >> ['parent_item1', 'parent_item2', 'child1_item', 'child2_item']
child1.print_list()
    # >> ['parent_item1', 'parent_item2', 'child1_item', 'child2_item']
child2.print_list()
    # >> ['parent_item1', 'parent_item2', 'child1_item', 'child2_item']

我该如何得到下面的结果呢?

['parent_item1', 'parent_item2', ]
['parent_item1', 'parent_item2', 'child1_item', ]
['parent_item1', 'parent_item2', 'child2_item', ]
暂无标签

4 个回答

0

你可以使用元类来获取更新后的列表作为类的属性,我不太确定如果不使用元类是否也能做到这一点。

class A(type):                                                
    foo = ['a']
                                                              
    def __new__(self, name, bases, attrs):                         
        if foo := attrs.get('foo'):                                               
            attrs['foo'] = self.foo + foo                       
        return type.__new__(self, name, bases, attrs)                                    
                                                              
                                                              
class B(metaclass=A):                                         
    foo = ['b']      

A.foo 
# >> ['a']
B.foo 
# >> ['a', 'b']
                                     
0

你想给Parent这个类写一个构造函数。问题是,所有的Parent实例都在使用同一个列表,这个列表是在Parent被声明的时候创建的。你其实想要的是:

class Parent(object):
    def __init__(self):
        self.a_list = ['parent_item1', 'parent_item2', ]
    def print_list(self):
        print(self.a_list)

这样,每当你创建一个新的Parent实例时,都会生成一个全新的列表,里面包含['parent_item1', 'parent_item2', ]

0

我解决了这个问题,方法非常简单明了。其实不需要用到super或者init()这个东西。

class Parent(object):
    a_list = ['parent_item1', 'parent_item2', ]

    def print_list(self):
        print(self.a_list)


class Child1(Parent):
    a_list = Parent.a_list + ['child1_item', ]


class Child2(Parent):
    a_list = Parent.a_list + ['child2_item', ]


parent = Parent()
child1 = Child1()
child2 = Child2()

parent.print_list()
    # >> ['parent_item1', 'parent_item2', ]
child1.print_list()
    # >> ['parent_item1', 'parent_item2', 'child1_item', ]
child2.print_list()
    # >> ['parent_item1', 'parent_item2', 'child2_item']
3

list += other_list 是在原来的列表上直接添加内容。也就是说,它会把 other_list 的元素加到 list 里面,而不会创建一个新的列表。如果你使用 + 这个符号,它会返回一个新的列表,原来的列表不会改变。

class Parent(object):
    a_list = ['parent_item1', 'parent_item2', ]
    def print_list(self):
        print(self.a_list)

class Child1(Parent):
    def __init__(self, *args, **kwargs):
        super(Child1, self).__init__(*args, **kwargs)
        self.a_list = self.a_list + ['child1_item']  # <-------

class Child2(Parent):
    def __init__(self, *args, **kwargs):
        super(Child2, self).__init__(*args, **kwargs)
        self.a_list = self.a_list + ['child2_item']  # <-------


parent = Parent()
child1 = Child1()
child2 = Child2()
parent.print_list()
child1.print_list()
child2.print_list()

输出结果:

['parent_item1', 'parent_item2']
['parent_item1', 'parent_item2', 'child1_item']
['parent_item1', 'parent_item2', 'child2_item']

另外,你也可以复制父类的列表:

...
self.a_list = self.a_list[:]
self.a_list += ['child1_item']

撰写回答