python - 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?
解决方案
您的问题是parse
调用cls(name)
,它只有一个参数,但cls
is Employee
or 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
对象,例如,又不想同时提供薪水,这是不可避免的。
推荐阅读
- postgresql - Invalid multibyte character for locale when attempting to create Trigrams index
- powershell - 将 awk 过滤转换为 Windows 命令行等效项
- ios - 表格视图中的单元格展开未在 swift 中正确显示
- python - 使用 pandas 数据框中的值更新字符串中的值
- node.js - Nodejs,asny 同步
- javascript - 在 AngularJS 中使用 $scope 更新 ChartJs 图表
- angular - “承诺”类型上不存在属性“订阅”
' @ionic-native/background-geolocation 插件中的错误 - java - 直到第二次单击选项卡时,Android 片段才会加载数据
- javascript - 如何在 Angular 中添加 Swarmify 视频播放器插件 JS 文件?
- r - 创建附加循环 Dplyr