首页 > 解决方案 > Inheritance issue creating objects

问题描述

Person.py

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

    @classmethod
    def parse(cls, name):
        return cls(name)

Employee.py

class Employee(Person):
    def __init__(self, ename, esalary):
        super().__init__(ename)
        self.salary = esalary

    @classmethod
    def parse(cls, data):
        person = super().parse(data["name"])
        person.salary = data["salary"]
        return person

Customer.py

class Customer(Person):
    def __init__(self, ename, country):
        super().__init__(ename)
        self.country = country

    @classmethod
    def parse(cls, data):
        person = super().parse(data["name"])
        person.country = data["country"]
        return person

main.py

emp_data = {
    "name": "john",
    "salary": 1000
}
emp = Employee.parse(emp_data)
print(type(emp))
print(emp.name)
print(emp.salary)


cust_data = {
    "name": "peter",
    "country": "USA"
}
cust = Customer.parse(cust_data)
print(type(cust))
print(cust.name)
print(cust.country)

errors

TypeError                                 Traceback (most recent call last)
<ipython-input-32-a5abd51d9870> in <module>()
     36     "salary": 1000
     37 }
---> 38 emp = Employee.parse(emp_data)
     39 print(type(emp))
     40 print(emp.name)

<ipython-input-32-a5abd51d9870> in parse(cls, data)
     14     @classmethod
     15     def parse(cls, data):
---> 16         person = super().parse(data["name"])
     17         person.salary = data["salary"]
     18         return person

<ipython-input-32-a5abd51d9870> in parse(cls, name)
      5     @classmethod
      6     def parse(cls, name):
----> 7         return cls(name)
      8 
      9 class Employee(Person):

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

This example is just for reproducing the problem in the actual code. The actual parse functions involve complex logic.

In the above example, Employee and Customer classes extend Person class. According to the error, init method of Person class which is invoked by parse form same class, is expecting esalary. But there is no esalary property on Person init method.

What's wrong with my program? I think I did not understand inheritance properly. Please, correct me. First of all, did I structure my program correctly?

标签: pythoninheritance

解决方案


您的问题是parse调用cls(name),它只有一个参数,但clsis Employeeor Customer,不一定Person。您必须在构建时(调用时)提供附加参数(薪水/国家/地区)parse,或者在未提供时为它们提供默认值。

通过以下方式向构造函数提供额外需要的参数parse

@classmethod
def parse(cls, name, *args, **kwargs):
    return cls(name, *args, **kwargs)

这将允许您执行以下操作:

Employee.parse(name, salary)  # Really no different than Employee(name, salary)

或者在子构造函数中为这些参数添加默认值,以便可以仅使用名称构造它们:

class Customer(Person):
    def __init__(self, ename, country=None):
        # ...

class Employee(Person):
    def __init__(self, ename, esalary=None):
        # ...

请注意,这可能会导致您的None值在这些属性中浮动,但如果您想构建一个新的Employee对象,例如,又不想同时提供薪水,这是不可避免的。


推荐阅读