gpt4 book ai didi

python - 控制用 attrs 定义的派生类的 init 中的参数顺序

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

attrs 中,生成的 init 方法的参数顺序由类中属性定义的顺序 + MRO(一种定义总顺序的标准方法基于多重继承关系)。这对我的用例不利,但似乎没有任何灵 active 。这是用例:

我正在使用 attrs 来定义一些建模图形基元的类。这些基元是相关的,因为它们都需要数据来处理和生成具有给定高度和宽度的图形,这些高度和宽度都有默认值。所以在顶层有一个类

@attr.s
class BaseGraphics:
data = attr.ib()
height = attr.ib(default=300)
width = attr.ib(default=400)

由此派生出三个类,UnivariateGraphicsBivariateGraphicsMultivariateGraphics,它们在 data 中使用一个、两个或多个列 分别。让我展示一个:

@attr.s
class BivariateGraphics(BaseGraphics):
x = attr.ib()
y = attr.ib()

单变量情况下只有 x 和多变量情况作为单个 columns 属性。这失败了,因为在 MRO 中,xy 出现在 heightwidth 之后,但是 xy 是必需的,而 heightwidth 不是。准确的错误是

ValueError: No mandatory attributes allowed after an attribute with 
a default value or factory. Attribute in question:
Attribute(name='x', default=NOTHING, validator=None, repr=True,
cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None,
converter=None, kw_only=False)

我可以像第一列和第二列一样为 xy 设置默认值,但顺序仍然是错误的。例如,如果想写类似的东西

BivariateGraphics(iris_data, "petalWidth", "sepalWidth")

第二个和第三个参数将被解释为 heightwidth,而不是 xy。我可以通过将所有属性设为仅 data 关键字来防止此错误,但我不支持此语法。通过阅读几个相关问题,例如#38,这似乎是推荐的方法。关闭,但没有雪茄。

另一种解决方法是将 heightwidth 分别添加到每个派生类。这将违反 DRY 原则,并且无法表达和执行类之间的这种共性。有超过三个类,它会变得非常讨厌。

这不仅仅是一个“学术”问题。我在包 autosig 中使用 attrs 来帮助一致地定义 API。这个又在一个统计图形包altair_recipes中用到了,上面的情况确实会出现(嗯,下个版本的时候我需要添加height宽度到所有图形基元)。

我可以向开发人员提出问题,但由于主要开发人员开玩笑地(?)威胁那些使用电击进行子类化的人,我觉得这将是徒劳的。我会对不需要 DRY 违规或样板的基于非继承的解决方案感兴趣。谢谢

最佳答案

在这种情况下,您希望能够依赖稳定的 API(尤其是在子类化时,乍一看顺序并不总是很清楚),我们强烈建议使用类方法工厂(这也是我的想法)倾向于在我自己的代码中使用)。每当您开始更改类中的内容时,事情就会变得一团糟,尤其是当您必须浏览多个层次结构时。因此,最好根据自己的条件构建 API 并将 attrs 仅用于管道。

but since the main dev has jokingly (?) threatened people who subclass with electroshock

虽然我确实对子类化持相当强硬的立场,但我很难想象记录下来用电击威胁除我自己以外的任何人,除非是在志同道合的 friend 之间开玩笑。如果我确实有这样的判断失误,我深表歉意。

关于python - 控制用 attrs 定义的派生类的 init 中的参数顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52430122/

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