如何在实例化时改变数据类参数?

How to mutate dataclass argument upon instantiation?

提问人:Jason Strimpel 提问时间:11/7/2023 更新时间:11/7/2023 访问量:69

问:

我有一个看起来像这样的:dataclass

@dataclass
class AllLastTick:
    tick_type_mapping = {
        0: "bid_size",
        1: "bid_price",
        2: "ask_price",
        3: "ask_size",
        4: "last_trade_price",
        5: "last_trade_size"
    }
    time: int
    tick_type: int
    price: float
    size: Decimal

我是这样实例化的:

tick_data = (
    time,
    tick_type,
    price,
    size
)

tick = AllLastTick(*tick_data)

结果如下所示:

AllLastTick(time=1699358716, tick_type=2, price=178.49, size=Decimal('200'))

我想做的是将参数转换为实例化类时的值。tick_typeAllLastTick .tick_type_mapping

理想的结果如下所示:

AllLastTick(time=1699358716, tick_type="ask_price", price=178.49, size=Decimal('200'))

我试过使用这样的东西:

...
tick_type: int = field(default_factory=lambda x: tick_type_mapping[x])
...

据我所知,这不起作用,因为字段不能可变(在这一点上打上问号)。

我怎样才能做到这一点?

蟒蛇 python-dataclasses

评论

0赞 Jason Strimpel 11/7/2023
我可以更新到键入tick_typestr
0赞 Abdul Niyas P M 11/7/2023
好吧,如果是这样的话,我建议更新你的问题。
0赞 jkr 11/7/2023
你能在数据类之外创建一个变量,然后在实例化时使用它吗?tick_type_mappingAllLastTick
0赞 jsbueno 11/9/2023
恕我直言,这个问题传达了一种非常有用的模式,到目前为止,该语言(数据类、参数传递或类型系统)尚未接受该模式,即接受一个字段的更广泛类型,并将值强制为严格的类型。任何读到这篇文章的人:我们可以谈谈核心语言本身的提案。

答:

2赞 Nathan Furnal 11/7/2023 #1

使用怎么样?请参阅文档__post_init__

from dataclasses import dataclass, field
from decimal import Decimal

class AllLastTick:
    tick_type_mapping = {
        0: "bid_size",
        1: "bid_price",
        2: "ask_price",
        3: "ask_size",
        4: "last_trade_price",
        5: "last_trade_size"
    }
    time: int
    tick_idx: int
    tick_type: str = field(init=False)
    price: float
    size: Decimal
    def __post_init__(self):
        self.tick_type = self.tick_type_mapping[self.tick_idx]

然后

tick = AllLastTick(*tick_data)

将使用索引并为您定义分时类型。您只需要将密钥存储在另一个属性 () 中。tick_idx

评论

1赞 jsbueno 11/9/2023
另外:可以是 here,它将使用 .但是,在序列化或以其他方式读取类字段时,可能不需要它本身。tick_Type@propertytick_idxtick_ix