Python 如何构造没有逻辑的配置数据类?
在我们的项目中,我们需要描述我们正在使用的硬件的属性。然后在程序中使用这些信息来决定程序应该如何执行 我正试图找到适合这项工作的最佳数据结构,我一直在想,在这种情况下,pythonic方法会是什么Python 如何构造没有逻辑的配置数据类?,python,python-3.x,design-patterns,architecture,Python,Python 3.x,Design Patterns,Architecture,在我们的项目中,我们需要描述我们正在使用的硬件的属性。然后在程序中使用这些信息来决定程序应该如何执行 我正试图找到适合这项工作的最佳数据结构,我一直在想,在这种情况下,pythonic方法会是什么 这些属性在运行时不会更改,也不应意外更改 此外,某些硬件非常相似,因此使用继承机制仅指定两个硬件之间的差异,而不是重新键入所有属性可能是有意义的 许多属性来自可能值的列表(枚举) 添加新属性或重命名现有属性应该很容易。例如,如果另一个硬件属性与程序的执行相关,我们可以轻松添加一个新属性(在编码
- 这些属性在运行时不会更改,也不应意外更改
- 此外,某些硬件非常相似,因此使用继承机制仅指定两个硬件之间的差异,而不是重新键入所有属性可能是有意义的
- 许多属性来自可能值的列表(枚举)
- 添加新属性或重命名现有属性应该很容易。例如,如果另一个硬件属性与程序的执行相关,我们可以轻松添加一个新属性(在编码时)。如果现有属性的命名与新属性太相似,我们可能需要对其进行重命名,以便更清楚地了解它们之间的区别
- 最后一个要求(我认为这是一个有问题的要求)是我们希望这些属性不依赖于任何逻辑(例如,它们应该是直接赋值)。以下是对最后一项要求的澄清:
name=“Joe”#好的 如果性别==gender.male:#不正常 name=“乔” 其他: name=“Jane”
- 我已经研究了
,但这并没有限制赋值逻辑dataclass
- 我已经检查了@property decorator,但这也没有限制赋值逻辑
- 我已经选中了
,但这会造成继承问题(仍然允许添加逻辑)NamedTuple
- 我见过一些帖子将源代码意识与
结合使用,但这似乎有点骇人听闻ast.parse
numberofoors
,在上面的示例中),而不是只执行纯赋值。我正在寻找一种在编码时阻止/防止这种情况发生的方法
是否有更适合此工作的结构?不清楚您所说的“这不限制分配逻辑”是什么意思。例如,您可以将数据类设置为
冻结=True
,因此对字段的赋值会引发异常。还不清楚“添加新属性或重命名现有属性应该很容易”是什么意思。。因为您还说过“这些属性在运行时不会更改”。我认为这里的示例比需求列表更有用。请给出一个预期使用的示例,以及您尝试使用DataClass或namedtuples的情况,以及失败的原因。@GinoMempin我已经添加了一个示例来说明我如何使用它。JSON实现(未显示,因为它非常复杂)解决了避免属性中任何逻辑的需求,而我刚才添加的示例满足其他需求,但它允许添加任意逻辑(代码)。检查示例中的注释,以查看哪个部分存在问题。我还添加了关于添加/重命名属性的说明。如果您认为任何进一步的澄清都会有用,请告诉我。不清楚您所说的“这不限制分配逻辑”是什么意思。例如,您可以将数据类设置为冻结=True
,因此对字段的赋值会引发异常。还不清楚“添加新属性或重命名现有属性应该很容易”是什么意思。。因为您还说过“这些属性在运行时不会更改”。我认为这里的示例比需求列表更有用。请给出一个预期使用的示例,以及您尝试使用DataClass或namedtuples的情况,以及失败的原因。@GinoMempin我已经添加了一个示例来说明我如何使用它。JSON实现(未显示,因为它非常复杂)解决了避免属性中任何逻辑的需求,而我刚才添加的示例满足其他需求,但它允许添加任意逻辑(代码)。检查示例中的注释,以查看哪个部分存在问题。我还添加了关于添加/重命名属性的说明。如果您认为任何进一步的澄清都是有用的,请告诉我。
from dataclasses import dataclass, field
from enum import Enum
class TransmissionType(Enum):
MANUAL = "Manual"
AUTOMATIC = "Automatic"
class BodyType(Enum):
COUPE = "Coupe"
WAGON = "Wagon"
@dataclass (frozen=True)
class Car:
transmissionType: TransmissionType = field(init=False)
bodyType: BodyType = field(init=False)
numberOfDoors: int = field(init=False)
consumptionPer100km: int = field(init=False)
@dataclass (frozen=True)
class FancyModel2019(Car):
transmissionType = TransmissionType.MANUAL
bodyType = BodyType.COUPE
consumptionPer100km = 5
if bodyType == BodyType.COUPE: #This should not be possible
numberOfDoors = 3
else:
numberOfDoors = 5
@dataclass (frozen=True)
class FancyModel2020(FancyModel2019):
consumptionPer100km = 4
myCar = FancyModel2020()
print(myCar.numberOfDoors)