当前位置: 首页 > 知识库问答 >
问题:

使用python数据类作为用户输入的DTO的最佳实践

叶经略
2023-03-14

我想使用蟒蛇数据类作为数据容器,它可以传递给程序中的其他类。具体来说,我想在数据类中存储所有默认值,但可以通过用户输入在我的主类中更改值。随后,更新的数据对象应该被传递给所有其他使用它执行计算的类。此外,数据类已经利用post_init准备了一些数据供以后使用。

目前我的解决方案示意性地是

from dataclasses import dataclass


@dataclass
class DataContainer:
    dat1: int = 1
    dat2: str = 'something'
    scale: float = 1.5

    def __post_init__(self):
        self._scaled_var = self.alter_scale(self.scale)

    @staticmethod
    def alter_scale(scale_in):
        return scale_in * 2 / 3


class SubClassA:
    def __init__(self, Data):
        self.dc = Data

    def do_it_function(self, x):
        return x ** 2 + self.dc.dat1


class Main:
    def __init__(self, Data=DataContainer, **kwargs):
        self.dc = Data(**kwargs)
        self.di = SubClassA(self.dc)

问题是,我不喜欢把**kwargs传递给我的数据类,因为对我来说这感觉像是糟糕的练习。然而,它的行为完全像我想要的...

解决这个问题的干净方法是什么?

共有1个答案

胡志
2023-03-14

虽然我不完全理解您试图做什么,但一种方法可能是将所有现有模型类转换为数据,并使用InitVar和field等辅助函数定义属性,如下所示。

from dataclasses import dataclass, InitVar, field


@dataclass
class DataContainer:
    dat1: int = 1
    dat2: str = 'something'
    scale: float = 1.5

    def __post_init__(self):
        self._scaled_var = self.alter_scale(self.scale)

    @staticmethod
    def alter_scale(scale_in):
        return scale_in * 2 / 3


@dataclass
class SubClassA:
    dc: DataContainer

    def do_it_function(self, x):
        return x ** 2 + self.dc.dat1


@dataclass
class Main:
    di: SubClassA = field(init=False)
    data: InitVar[DataContainer] = DataContainer()

    def __post_init__(self, data: DataContainer):
        self.di = SubClassA(data)

    @property
    def dc(self):
        return self.di.dc


m = Main()
print(m)
print()

data = DataContainer(123, 'hello world!')
m2 = Main(data)
print(m2.di)
print(m2.dc)

输出:

Main(di=SubClassA(dc=DataContainer(dat1=1, dat2='something', scale=1.5)))

SubClassA(dc=DataContainer(dat1=123, dat2='hello world!', scale=1.5))
DataContainer(dat1=123, dat2='hello world!', scale=1.5)
 类似资料:
  • 问题内容: 据我了解,有两种方法可以做Python装饰器,既可以使用类的,也可以定义并调用函数作为装饰器。这些方法的优点/缺点是什么?有一种首选的方法吗? 例子1 例子2 问题答案: 说每种方法是否都具有“优势”是相当主观的。 但是,如果对幕后的事物有一个很好的了解,那么自然就可以为每种场合选择最佳选择。 装饰器(谈论函数装饰器)只是一个以函数为输入参数的可调用对象。Python有其相当有趣的设计

  • 使用Spring Data nad Querydsl,我们可以只声明存储库接口并跳过实现类。一些具有特定名称或使用@Query注释的方法,仅此而已。 但是有时我想使用JPAQuery并自己定义方法的主体,比方说 null

  • 问题内容: 尽管显然不是所有场景都可以用一个设计覆盖,但现在是否普遍认为应该在表示层和业务层(本地或远程)之间来回传递ORM类,从而取代了对数据传输对象的需求?据我所知,使用ORM类会带来不必要的急切加载,上下文管理问题和紧密耦合的问题,但还可以节省大量时间,并使事情变得简单。现在是否存在一种标准的方法(通常在大多数情况下)通常会优先选择另一方法? 问题答案: 这是一个非常有趣的问题,在过去的两年

  • 另一个选项是使用simple_format或.html_safe或sanitize(fieldname)在视图中显示数据时进行sanitize。我应该在每个字段的所有视图中以及插入上进行消毒吗?在任何地方都必须手动执行此操作似乎不是很有条不紊 谢谢你的帮助

  • 问题内容: 我开发Joomla网站/组件/模块和插件,并且每隔一段时间我都需要使用JavaScript来加载页面时触发事件的功能。在大多数情况下,这是使用函数完成的。 我的问题是: 这是在页面加载时触发JavaScript事件的最佳方法,还是有更好/更新的方法? 如果这是触发页面加载事件的唯一方法,那么确保多个事件可以由不同的脚本运行的最佳方法是什么? 问题答案: 可以,但是您可能已经注意到, 它

  • 问题内容: 我正在开发一个J2ME应用程序,该应用程序具有要存储在设备上的大量数据(大约1MB,但是可变)。我不能依靠文件系统,所以我卡住了记录管理系统(RMS),该系统允许多个记录存储,但每个记录存储空间都有限。我最初的目标平台Blackberry将每个限制为64KB。 我想知道是否还有其他人必须解决在RMS中存储大量数据的问题,以及他们如何进行管理?我正在考虑必须计算记录大小并在多个存储区中拆