gpt4 book ai didi

python - 在 Python 数据类中使用描述符作为字段的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-04 14:53:17 25 4
gpt4 key购买 nike

我一直在研究 python 数据类并且想知道:制作一个或某些字段描述符的最优雅或最 pythonic 的方法是什么?

在下面的示例中,我定义了一个 Vector2D 类,它应该根据其长度进行比较。

from dataclasses import dataclass, field
from math import sqrt

@dataclass(order=True)
class Vector2D:
x: int = field(compare=False)
y: int = field(compare=False)
length: int = field(init=False)

def __post_init__(self):
type(self).length = property(lambda s: sqrt(s.x**2+s.y**2))

Vector2D(3,4) > Vector2D(4,1) # True

虽然此代码有效,但它会在每次创建实例时触及类,是否有更易读/更少hacky/更有意的方式来一起使用数据类和描述符?

只需将 length 作为属性而不是字段即可,但这意味着我必须编写 __lt__, et.al.我自己。

我发现的另一个解决方案同样没有吸引力:

@dataclass(order=True)
class Vector2D:
x: int = field(compare=False)
y: int = field(compare=False)
length: int = field(init=False)

@property
def length(self):
return sqrt(self.x**2+self.y**2)

@length.setter
def length(self, value):
pass

引入一个无操作 setter 是必要的,因为显然数据类创建的 init 方法试图分配给 length 即使没有默认值并且它显式设置 init=False ...

肯定有更好的方法吧?

最佳答案

可能无法回答您的确切问题,但您提到您不想将 length 作为属性和 not 字段的原因是因为您必须这样做

write __lt__, et.al by myself

虽然您确实必须自己实现 __lt__,但实际上您可以只实现那个

from functools import total_ordering
from dataclasses import dataclass, field
from math import sqrt

@total_ordering
@dataclass
class Vector2D:
x: int
y: int

@property
def length(self):
return sqrt(self.x ** 2 + self.y ** 2)

def __lt__(self, other):
if not isinstance(other, Vector2D):
return NotImplemented

return self.length < other.length

def __eq__(self, other):
if not isinstance(other, Vector2D):
return NotImplemented

return self.length == other.length


print(Vector2D(3, 4) > Vector2D(4, 1))

之所以可行,是因为 total_ordering 只是添加了所有其他基于 __eq____lt__

的相等方法

关于python - 在 Python 数据类中使用描述符作为字段的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68652100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com