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

zec*_*use 6 python repr python-dataclasses

我有一个 Node 类,以十六进制和 HSV 形式保存 RGB 数据。我将使用它以各种方式对颜色进行排序,并且希望 HSV 元组保持浮点形式进行比较,而不是每次使用时都从字符串进行转换。有没有一种方法可以指定数据类字段应该以类似于默认值的特定方式格式化值default_factory,即 a 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
Run Code Online (Sandbox Code Playgroud)

当我计算出不同的类型时,我正在打印节点,并且看到浮点数中有 10 个不必要的数字,这让人分心。据我所知,我自己实现会更好吗?__repr__该类实现自己的类,而不是依赖数据类生成的类?

我查看该__repr__值的原因是因为它是由数据类自动生成的,并且可以比仅查看视觉输出更容易地区分几乎相同的颜色。如果我知道颜色的实际数字是多少,就会更容易找出下一步要更改或执行的操作。输出末尾的一部分:

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))
Run Code Online (Sandbox Code Playgroud)

基本上,是否可以为数据类字段指定格式,类似于如何指定函数default_factory,以便生成器__repr__为我格式化该字段,这样我就不必编写自己的字段?

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))
Run Code Online (Sandbox Code Playgroud)
Node(hex=(238, 51, 0), hsv=(12.857, 100.000, 93.333))
Run Code Online (Sandbox Code Playgroud)

Jas*_*ijn 5

数据类库当前不支持这样的格式化字段。默认情况下为每个包含的字段生成的代码__repr__始终采用 form f'field={self.field!r}'。您必须编写自己的__repr__.