根据属性值填充类

0 投票
1 回答
25 浏览
提问于 2025-04-14 15:34

我有一些数据是以重复的方式流入的,我需要在把这些数据放到一个@dataclass之前,先应用一些业务逻辑。

这个数据类的结构如下:

class Foo:
   color: str
   engine: int
   petrol: int
   diesel: int

数据包括一个颜色的枚举值,以及两对两位数字,这些数字是一个一个地流入的。

Red, 3, 1, 4, 5, Blue, 2, 2, 7, 5, Orange, 5, 2, 6, 8 etc...

红色被分配给颜色属性,31被分配给引擎属性。

如果颜色属性是红色、蓝色或黄色,那么最后两位数字(45)会被分配给汽油属性。

如果颜色属性是橙色或绿色,那么最后两位数字(45)会被分配给柴油属性。

我尝试了这个:

digits = 0
positional_counter = 0

# Set first attribute color
if value in ["Red", "Blue", "Orange", "Green"]:
     self.foo.color = value
     positional_counter += 1

# Set second attribute - joining the digits
if positional_counter == 1:
     digits = value * 10
     positional_counter += 1
if positional_counter == 2:
     self.foo.engine = digits + value
     digits = 0
     positional_counter += 1

# Whether the second set of digits is set against petrol or diesel depends on color attrib
if self.foo.color in ["Red", "Blue"]:
   if positional_counter == 3:
       digits = value * 10
       positional_counter += 1
   if positional_counter == 4:
       self.foo.petrol = digits + value
       positional_counter = 0
if self.foo.color in ["Orange", "Green"]:
   if positional_counter == 3:
       digits = value * 10
       positional_counter += 1
   if positional_counter == 4:
       self.foo.diesel = digits + value
       positional_counter = 0
    

有没有更好的方法来做这个?上面的代码看起来很难读,也很乱。而且数据可能会在一个颜色枚举值之前就开始流入,这种情况下可以跳过前面一两个值,直到遇到颜色枚举值来确定开始的位置。

1 个回答

0

你可能需要创建两个类,分别叫做 DieselPetrol,这两个类都要从 Vehicle 这个基类继承。基类主要关注的是燃料的数量,而子类则负责记录燃料类型的信息。

@dataclass
class Vehicle:
    color: ColorType
    engine: int
    fuel: int


@dataclass
class Diesel(Vehicle):
    pass


@dataclass
class Petrol(Vehicle):
    pass

接下来,定义一个字典,用来把颜色和燃料类型对应起来:

d = {
      Red: Diesel,
      Blue: Diesel,
      Yellow: Diesel,
      Green: Petrol,
      Orange: Petrol
    }

在开始创建任何东西之前,先处理一下数据。

def process_data(d) -> Iterable[tuple[Color, int, int]]:
    # Turn [Red, 3, 1, 4, 5, ...] into [(Red, 31, 45), ...]

然后,只需使用你之前定义的字典,根据颜色来选择实例化哪个类:

data = [Red, 3, 1, 4, 5, Blue, 2, 2, 7, 5, Orange, 5, 2, 6, 8]
for color, engine, fuel in process_data(data):
    obj = d[color](color, engine, fuel)
    ...

    

撰写回答