超级构造函数使用* args和** kwargs for __init__

时间:2016-11-04 20:38:58

标签: python class oop

假设我们有一个基类Person和一个子类Employee(参见底部的代码)。

编码一段时间后,我发现我需要为base添加更多属性:

class Person:

    def __init__(self, first, last, new_att1, new_att2):

然后我需要转到子类,修改为以下内容:

class Employee(Person):

    def __init__(self, first, last, new_att1, new_att2, staffnum):
        Person.__init__(first, last,  new_att1, new_att2)
        self.staffnumber = staffnum

说我有5个子类。每次我更新基类属性时,我需要在上面重复所有5个子类。任何人都可以帮助指出一种优雅的方式来管理它吗?

原班级:

class Person:

    def __init__(self, first, last):
        self.firstname = first
        self.lastname = last

    def __str__(self):
        return self.firstname + " " + self.lastname

class Employee(Person):

    def __init__(self, first, last, staffnum):
        Person.__init__(first, last)
        self.staffnumber = staffnum

1 个答案:

答案 0 :(得分:2)

一个选项是仅使用关键字参数(无论如何,当你有很多参数时,这是一个好主意):

class Person(object):
    def __init__(self, firstname, lastname, new_att1, new_att2):
        self.firstname = firstname
        self.lastname = lastname

    def __str__(self):
        return "%s %s" % (self.firstname, self.lastname)


class Employee(Person):
    def __init__(self, staffnumber, **kwargs):
        super(Employee, self).__init__(**kwargs)
        self.staffnumber = staffnumber


e = Employee(
    firstname="Foo",
    lastname="Bar",
    staffnumber=42,
    new_att1=True,
    new_att2=False,
)

缺点是子类构造函数不再具有显式签名,这使得它们更难以阅读和推理。