'Loading different subclasses from json
There's a good inheritance vs composition tutorial at https://realpython.com/inheritance-composition-python/ which gives an example of extending the base class Employee into two subclasses, SalaryEmployee and HourlyEmployee. This gives you different methods on each employee type such as paying by the hour or paying by the month.
You then instantiate each employee individually using the correct subclass:
john = hr.SalaryEmployee(id=1, name='John Smith', monthly_salary=1500)
jane = hr.HourlyEmployee(id=2, name='Jane Doe', working_hours=40, hourly_salary=15)
If I am loading the employee data from a data structure that specifies the employeetype within each record, e.g.:
employee_data = [
{
'name': 'John Smith',
'id' : 1,
'type' : 'SalaryEmployee',
'monthly_salary' : 1500
},
{
'name' : 'Jane Doe',
'id' : 2,
'type' : 'HourlyEmployee',
'working_hours' : 40,
'hourly_salary' : 15
}
]
...how do I dynamically assign the correct subclass to each employee?
A set of "if employee['type'] == ..." statements would work, but means that whenever we add a new subclass we have to modify the instantiation code which seems inelegant. Is there a more pythonic way?
I'm looking for something along the lines of
employee_objects = [CorrectSubClassOfEmployee(**x) for x in employee_data]
I absolutely cannot be the first person to ask this, but my google-fu is not turning up the right answer
Thanks!
Solution 1:[1]
You will want getattr:
employee_objects = [hr.getattr(x['type'])(**x) for x in employee_data]
(Obviously, the appropriateness of the **x will depend on how you've written the constructor for your (sub)class)
Solution 2:[2]
Use a dict
employee_subclasses = {
'SalaryEmployee': hr.SalaryEmployee,
'HourlyEmployee': hr.HourlyEmployee,
}
employee_objects = [employee_subclasses[x.pop('type')](**x) for x in employee_data]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alex |
| Solution 2 | Iain Shelvington |
