简体   繁体   English

数据类字段可以为 repr 格式化其值吗?

[英]Can a dataclass field format its value for the repr?

I have a Node class holding RGB data in both hex and HSV form.我有一个节点类以十六进制和 HSV 形式保存 RGB 数据。 I'll be using this to sort colors in various ways and would prefer the HSV tuple to remain in float form for comparisons instead of converting from a string for every use.我将使用它以各种方式对颜色进行排序,并且希望 HSV 元组保持浮动形式以进行比较,而不是每次使用都从字符串转换。 Is there a way to specify to the dataclass field that it should format the value in a specific way similar to default values with the default_factory , ie a repr_factory ?有没有办法向数据类字段指定它应该以类似于default_factory的默认值的特定方式格式化值,即repr_factory

def RGB2HSV(r, g, b):
    '''Returns HSV values in the range H = [0, 360], S = [0, 100], V = [0, 100]'''
    r, g, b = r / 255, g / 255, b / 255
    maxRGB = max(r, g, b)
    minRGB = min(r, g, b)
    delta = maxRGB - minRGB

    V = maxRGB
    if V == 0:
        return 0, 0, V
    
    S = delta / V * 100
    if S == 0:
        return 0, S, V * 100
    
    if V == r:
        H = (g - b) / delta
    elif V == g:
        H = 2 + (b - r) / delta
    else:
        H = 4 + (r - g) / delta
    H *= 60
    if H < 0:
        H += 360
    
    return H, S, V * 100

@dataclass
class Node:
    r: int = field(repr=False)
    g: int = field(repr=False)
    b: int = field(repr=False)
    hex: tuple[int, int, int] = field(init=False)
    hsv: tuple[float, float, float] = field(init=False)

    def __post_init__(self):
        self.hex = self.r, self.g, self.b # Generating random r, g, b numbers
        self.hsv = RGB2HSV(self.hex) # Converts the r, g, b to a tuple of floats

While I'm working out the different sorts, I'm printing out the Nodes and seeing 10 unnecessary digits of a float is distracting.虽然我正在研究不同的类型,但我正在打印节点并且看到 10 个不必要的浮点数会分散注意力。 As far as I can think of, would I just be better off implementing my own __repr__ for the class instead of relying on the dataclass generated one?据我所知,我最好为类实现自己的__repr__而不是依赖生成的数据类?

The reason I'm looking at the __repr__ value is because it's automatically generated by the dataclass and can make distinguishing between nearly identical colors easier than just looking at the visual output.我查看__repr__值的原因是因为它是由数据类自动生成的,并且可以比仅查看视觉输出更容易区分几乎相同的颜色。 It'll be easier to find out what to change or do next if I know what the actual numbers a color are.如果我知道颜色的实际数字是什么,那么找出要更改或下一步做什么会更容易。 A portion of the end of the output:输出结尾的一部分:

Node(hex=(238, 0, 0), hsv=(0.0, 100.0, 93.33333333333333))
Node(hex=(238, 17, 0), hsv=(4.285714285714286, 100.0, 93.33333333333333))
Node(hex=(238, 34, 0), hsv=(8.571428571428571, 100.0, 93.33333333333333))
Node(hex=(238, 51, 0), hsv=(12.857142857142858, 100.0, 93.33333333333333))
Node(hex=(255, 0, 0), hsv=(0.0, 100.0, 100.0))
Node(hex=(255, 17, 0), hsv=(4.0, 100.0, 100.0))
Node(hex=(255, 34, 0), hsv=(8.0, 100.0, 100.0))
Node(hex=(255, 51, 0), hsv=(12.0, 100.0, 100.0))

Basically, can a format be specified to a dataclass field, similar to how a function can be specified to default_factory , in order for the generated __repr__ to format the field for me so I don't have to write my own?基本上,可以为数据类字段指定格式,类似于如何为default_factory指定函数,以便生成的__repr__为我格式化字段,这样我就不必自己编写了?

...
    hsv: tuple[float, float, float] = field(init=False, repr_factory=lambda x: "{:.3f"}.format(x) for x in self.hsv)
...
Node(hex=(238, 51, 0), hsv=(12.857, 100.000, 93.333))

The dataclasses library currently does not support formatting fields like that.数据类库目前不支持这样的格式化字段。 The code generated in the default __repr__ for each included field is always in the form f'field={self.field!r}' .在默认__repr__中为每个包含的字段生成的代码始终采用f'field={self.field!r}'的形式。 You will have to write your own __repr__ .您将不得不编写自己的__repr__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM