简体   繁体   English

Python 使用数据类将基础 class object 转换为子类

[英]Python casting base class object to subclass using dataclass

I have an Employee base class and a Manager subclass.我有一个员工基础 class 和一个经理子类。 The subclass accepts an Employee obj and converts it to Manager.子类接受一个 Employee obj 并将其转换为 Manager。

The below code works fine, however I am trying to determine how I can create the same using a dataclass.下面的代码工作正常,但是我试图确定如何使用数据类创建相同的代码。

class Employee:
    def __init__(self, id: int, name: str):
        self.id = id
        self.name = name

class Manager(Employee):
    def __init__(self, employee: Employee, region: str):
        super().__init__(**vars(employee))
        self.region = region

e1 = Employee(1, 'Bob')
e2 = Employee(2, 'Sally')

# Sally gets promoted to manager of southwest region
e2 = Manager(e2, 'southwest')

Here is what I have so far, I'm not sure how to pass all the required parameters.这是我到目前为止所拥有的,我不确定如何传递所有必需的参数。

@dataclass
class Employee:
    id: int
    name: str

@dataclass
class Manager(Employee):
    region: str
    def __new__(cls, employee: Employee, region: str):
        obj = object.__new__(cls)
        super().__init__(obj, **vars(employee))
        return obj

e2 = Employee(2, 'Sally')
>>> Manager(e2, region='southwest')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'name'

I'm not sure what all of the __new__ metaclass hackery is meant to be accomplishing, but you very seldom need to override __new__ in Python, and this is no exception.我不确定所有__new__元类黑客的目的是什么,但是您很少需要在 Python 中覆盖__new__ ,这也不例外。

@dataclass
class Employee:
    id: int
    name: str

@dataclass
class Manager(Employee):
    region: str

e2 = Employee(2, 'Sally')
m2 = Manager(2, 'Sally', 'southwest')

Dataclasses are just that;数据类就是这样; classes meant to store data.用于存储数据的类。 Inheritance on dataclasses works like you'd expect.数据类上的 Inheritance 的工作方式与您预期的一样。 Just inherit and it all works out.只需继承,一切都会解决。

If you'd still rather take an Employee as argument, you can use __init__ rather than __new__如果您仍宁愿将Employee作为参数,则可以使用__init__而不是__new__

@dataclass
class Employee:
    id: int
    name: str

@dataclass
class Manager(Employee):
    region: str
    def __init__(self, employee: Employee, region: str):
        super().__init__(**vars(employee))
        self.region = region

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM