如何从父类扩展一个列表?

4
我有以下代码。父类拥有一个项目列表,子类需要添加到其中。
每个父对象实例都需要有这个列表,每个子类也需要有那个列表和额外的值。
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个回答

3
< p > list += other_list 是一种就地(in-place)扩展列表的方法。如果想要获得一个新的列表,请使用+运算符: < /p>
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']

0
你想为Parent创建一个构造函数。问题在于它们都共享同一个列表,该列表在声明Parent时被创建。相反,你需要:
class Parent(object):
    def __init__(self):
        self.a_list = ['parent_item1', 'parent_item2', ]
    def print_list(self):
        print(self.a_list)

这样,每当您构建一个父级对象时,都会创建一个全新的列表,其中包含['parent_item1', 'parent_item2', ]


0

我解决了它,解决方案非常简单和干净。不需要超级或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']

1
不错。我不同意 super 不是“简单和清晰”的说法。super 方法的设计目的是通过名称替代对父类的显式引用。这样,如果您更改当前类的继承树,super 将自动解决任何引用问题。 - Joel Cornett

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']
                                     

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接