我有以下代码:

class Person:
    def __init__(self, name, last_name, age):
        self.name = name
        self.last_name = last_name
        self.age = age 

class Student(Person):
    def __init__(self, name, last_name, age, indexNr, notes):
        super().__init__(name, last_name, age)
        self.indexNr = indexNr
        self.notes = notes

class Employee(Person):
    def __init__(self, name, last_name, age, salary, position):
        super().__init__(name, last_name, age)
        self.salary = salary
        self.position = position

class WorkingStudent(Student, Employee):
    def __init__(self, name, last_name, age, indexNr, notes, salary, position):
        Student.__init__(name, last_name, age, indexNr, notes)
        Employee.__init__(name, last_name, age, salary, position)

我想创建一个WorkingStudent实例,如下所示:

ws = WorkingStudent("john", "brown", 18, 1, [1,2,3], 1000, 'Programmer')

但它不起作用,我得到一个错误:

TypeError: __init__() missing 1 required positional argument: 'notes'

或者我做错了什么?此外,我已经在WorkingStudent类中try 了super(),但它只调用第一个通过的类的构造函数.i、 e在这种情况下Student

注意:我已经通过了多个StackOverflow查询,但我找不到任何可以回答这个问题的答案.(或许我错过了).

推荐答案

使用super()代替显式类沿mro传递参数:

class Person:
    def __init__(self, name, last_name, age):
        self.name = name
        self.last_name = last_name
        self.age = age 

class Student(Person):
    def __init__(self, name, last_name, age, indexNr, notes, salary, position):
        # since Employee comes after Student in the mro, pass its arguments using super
        super().__init__(name, last_name, age, salary, position)
        self.indexNr = indexNr
        self.notes = notes

class Employee(Person):
    def __init__(self, name, last_name, age, salary, position):
        super().__init__(name, last_name, age)
        self.salary = salary
        self.position = position

class WorkingStudent(Student, Employee):
    def __init__(self, name, last_name, age, indexNr, notes, salary, position):
        # pass all arguments along the mro
        super().__init__(name, last_name, age, indexNr, notes, salary, position)

# uses positional arguments            
ws = WorkingStudent("john", "brown", 18, 1, [1,2,3], 1000, 'Programmer')
# then you can print stuff like
print(f"My name is {ws.name} {ws.last_name}. I'm a {ws.position} and I'm {ws.age} years old.")
# My name is john brown. I'm a Programmer and I'm 18 years old.

判断MRO:

WorkingStudent.__mro__
(__main__.WorkingStudent,
 __main__.Student,
 __main__.Employee,
 __main__.Person,
 object)

创建WorkingStudent实例时,最好传递关键字参数,这样就不必担心弄乱参数的顺序.

由于WorkingStudent将属性的定义推迟到父类,因此立即使用super().__init__(**kwargs)向上传递层次 struct 中的所有参数,因为子类不需要知道它不处理的参数.第一个家长班是学生,所以是self .此处定义了索引NR等.mro中的下一个父类是Employee,所以从Student,再次使用super().__init__(**kwargs)将剩余的关键字参数传递给它.从Employee定义此处定义的属性,并再次通过super().__init__(**kwargs)将其余属性传递给mro(给个人).

class Person:
    def __init__(self, name, last_name, age):
        self.name = name
        self.last_name = last_name
        self.age = age 

class Student(Person):
    def __init__(self, indexNr, notes, **kwargs):
        # since Employee comes after Student in the mro, pass its arguments using super
        super().__init__(**kwargs)
        self.indexNr = indexNr
        self.notes = notes

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

class WorkingStudent(Student, Employee):
    def __init__(self, **kwargs):
        # pass all arguments along the mro
        super().__init__(**kwargs)

# keyword arguments (not positional arguments like the case above)
ws = WorkingStudent(name="john", last_name="brown", age=18, indexNr=1, notes=[1,2,3], salary=1000, position='Programmer')

Python相关问答推荐

Pandas实际上如何对基于自定义的索引(integer和非integer)执行索引

在Polars(Python库)中将二进制转换为具有非UTF-8字符的字符串变量

使用@ guardlasses. guardlass和注释的Python继承

"使用odbc_connect(raw)连接字符串登录失败;可用于pyodbc"

导入...从...混乱

多处理队列在与Forking http.server一起使用时随机跳过项目

与命令行相比,相同的Python代码在Companyter Notebook中运行速度慢20倍

lityter不让我输入左边的方括号,'

在Admin中显示从ManyToMany通过模型的筛选结果

OpenCV轮廓.很难找到给定图像的所需轮廓

在Google Drive中获取特定文件夹内的FolderID和文件夹名称

你能把函数的返回类型用作其他地方的类型吗?'

Pandas:将值从一列移动到适当的列

查找查找表中存在的列值组合

将相应的值从第2列合并到第1列(Pandas )

无法使用请求模块从网页上抓取一些产品的名称

将索引表转换为Numy数组

Pandas:根据相邻行之间的差异过滤数据帧

Python:使用asyncio.StreamReader.readline()读取长行

如何在networkx图中提取和绘制直接邻居(以及邻居的邻居)?