首页 > 解决方案 > Python:从基础Dataclass继承的Dataclass,如何将值从基础升级到新类?

问题描述

如何将值从基础数据类升级到继承自它的值?

示例(Python 3.7.2)

from dataclasses import dataclass

@dataclass
class Person:
    name: str 
    smell: str = "good"    

@dataclass
class Friend(Person):

    # ... more fields

    def say_hi(self):        
        print(f'Hi {self.name}')

friend = Friend(name='Alex')
f1.say_hi()

打印“嗨亚历克斯”

random_stranger = Person(name = 'Bob', smell='OK')

返回随机陌生人“人(名称='鲍勃',气味='OK')”

如何将 random_stranger 变成朋友?

Friend(random_stranger)

返回“朋友(姓名=人(姓名='鲍勃',气味='OK'),气味='好')”

结果我想得到“朋友(名字='鲍勃',气味='OK')”。

Friend(random_stranger.name, random_stranger.smell)

有效,但是如何避免复制所有字段?

还是我不能在从数据类继承的类上使用 @dataclass 装饰器?

标签: pythonpython-3.7python-dataclasses

解决方案


您所要求的是通过工厂方法模式@classmethod实现的,并且可以使用关键字直接在python类中实现。

只需在基类定义中包含一个数据类工厂方法,如下所示:

import dataclasses

@dataclasses.dataclass
class Person:
    name: str
    smell: str = "good"

    @classmethod
    def from_instance(cls, instance):
        return cls(**dataclasses.asdict(instance))

从此基类继承的任何新数据类现在都可以创建彼此的实例[1],如下所示:

@dataclasses.dataclass
class Friend(Person):
    def say_hi(self):        
        print(f'Hi {self.name}')

random_stranger = Person(name = 'Bob', smell='OK')
friend = Friend.from_instance(random_stranger)
print(friend.say_hi())
# "Hi Bob"

[1]如果您的子类引入没有默认值的新字段,您尝试从子类实例创建父类实例,或者您的父类具有仅 init 参数,则它将不起作用。


推荐阅读