使用显式关键字参数构建具有属性的数据类

发布于 2025-01-17 20:22:18 字数 1068 浏览 3 评论 0原文

我想将 dataclass 与不变的一起使用,该不变性在此类实例化对象的生命周期内不应更改。为了表明这些对象的实例变量为私有,它们的名称以下划线为前缀。这些实例变量可以通过使用 properties 轻松访问,如示例代码代码下面:

from dataclasses import dataclass

@dataclass
class C():
  _x: int = 3

  @property
  def x(self) -> int:
    return self._x

  def p(self) -> None:
    print(self._x)

当我想用明确的关键字参数调用此类构造函数时,出现问题。为此,我现在也必须使用下划线提供实例变量的名称。这似乎确实是违反直觉的,因为现在从班级的外部访问了私有变量。

a = C()      # sets 'a.x' to 3
a.p()        # prints 3

b = C(5)     # sets 'b.x' to 5
b.p()        # prints 5

c = C(_x=7)  # sets 'c.x' to 7
c = C(x=7)   # error: unexpected keyword argument 'x'

解决此问题的一种方法是,简单地提供 explicit 构造函数与匹配的参数:

def __init__(self, x: int = 3) -> None:
  self._x = x

但是,这似乎也非常违反直觉,因为这种方法与a dataclass的整个概念相矛盾。是否有一种方法可以将 dataclass 属性结合使用 ,它允许我在构造此类对象时使用显式关键字参数而无需 access/确认实例变量旨在私有

I would like to use a dataclass with an invariant that should not change during the lifetime of such instantiated objects. To indicate that the instance variables of these objects are private, their names are prefixed with an underscore. These instance variables can easily be accessed with the use of properties, as demonstrated with the example code below:

from dataclasses import dataclass

@dataclass
class C():
  _x: int = 3

  @property
  def x(self) -> int:
    return self._x

  def p(self) -> None:
    print(self._x)

The problem arises when I want to call the constructor of this class with explicit keyword arguments. To do so, I now have to provide the names of the instance variables with an underscore as well. This seems really counterintuitive, since the private variables are now accessed from outside of the class.

a = C()      # sets 'a.x' to 3
a.p()        # prints 3

b = C(5)     # sets 'b.x' to 5
b.p()        # prints 5

c = C(_x=7)  # sets 'c.x' to 7
c = C(x=7)   # error: unexpected keyword argument 'x'

One way to solve this problem, is to simply provide an explicit constructor with matching arguments:

def __init__(self, x: int = 3) -> None:
  self._x = x

However, this also seems to be dreadfully counterintuitive as this approach contradicts the whole notion of a dataclass. Is there a way to use a dataclass in combination with properties that allows me to use explicit keyword arguments when constructing such objects without having to access/acknowledge instance variables intended to be private?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阪姬 2025-01-24 20:22:18

数据类本质上是您可以将其附加到课堂的少数方法。这些方法提供了可重复使用的逻辑,数据级开发人员认为适用于某些用例。通过__ Init __参数设置私有字段不在这些用例中,因此您想要的不受dataclass模块的支持。

幸运的是,看来其他人编写了另一个涵盖此用例的模块: https:// pypi .org/project/dataclass-property/

您还可以查看一些替代框架,例如Pydantic,以查看它们是否更好地满足您的需求。

The dataclass is essentially a handful of methods that you can attach to your class. These methods provide reusable logic that dataclass developers thought applies to certain use cases. Setting private fields via __init__ arguments is not among these use cases, so what you want is not supported by the dataclass module.

Luckily, it appears someone else has written a different module that does cover this use case: https://pypi.org/project/dataclass-property/

You could also look at some alternative frameworks, such as pydantic, to see if they meet your needs better.

━╋う一瞬間旳綻放 2025-01-24 20:22:18

“ Dataclass”装饰者的“冷冻”论点会满足您的需求吗?


冷冻:如果true(默认值为false),则分配给字段将产生异常。这模仿了只读的冷冻实例。如果 setAttr ()或 delattr ()在类中定义,则升高TypeError。请参阅下面的讨论。

https://docs.python.org/3/library/library/dataclasses.htaclasses.html

Would the "frozen" argument of the "dataclass" decorator fulfill your needs?

"
frozen: If true (the default is False), assigning to fields will generate an exception. This emulates read-only frozen instances. If setattr() or delattr() is defined in the class, then TypeError is raised. See the discussion below.
"

https://docs.python.org/3/library/dataclasses.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文