将 python 数据类和属性一起使用真的存在错误吗?
我曾经在这里:
- 一起使用数据类和属性时出现奇怪的问题
- 数据类和属性装饰器
- Python 数据类的预期行为或错误?
- 数据类中的属性
- 推荐的方法是什么在 asdict 或序列化中包含数据类中的属性?
- 具有数据类属性的必需位置参数
- 组合 @dataclass 和 @property
- 在 Python 中协调数据类和属性
和无法找到为什么这个简单的代码工作正常的直接答案...
class Vehicle:
def __init__(self, wheels: int = 10):
self.wheels = wheels # -> calls the setter method
@property
def wheels(self) -> int:
print("getting wheels")
return self._wheels
@wheels.setter
def wheels(self, wheels: int):
print("setting wheels to", wheels)
self._wheels = wheels
v = Vehicle()
number = v.wheels # -> calls the getter method
print(number)
# last output: 10
...但是这个却不能(使用 dataclass
):
from dataclasses import dataclass
@dataclass
class Vehicle:
wheels: int = 10
@property
def wheels(self) -> int:
print("getting wheels")
return self._wheels
@wheels.setter
def wheels(self, wheels: int):
print("setting wheels to", wheels)
self._wheels = wheels
v = Vehicle()
number = v.wheels
print(number)
# output: <property object at 0x000002042D70DDB0>
即使当 dataclass 的官方文档 在开头就明确指出装饰器 @dataclass
准确地添加了第一个代码中的 __init__
方法,即这段代码:
@dataclass
class Vehicle:
wheels: int = 10
应该添加这个 __init__
:
def __init__(self, wheels: int = 10):
self.wheels = wheels
这真的是一个错误吗?
简短说明:
私有属性 _wheels
只能在 property
的方法内部访问,正如它应该的那样(以隔离它)。
我在其他线程(上面列出)中发现该属性是在方法外部操作的,公开为“公共”,这在某些情况下是不需要的。
I have been here:
- Weird Issue when using dataclass and property together
- Dataclasses and property decorator
- Expected behavior or a bug of python's dataclasses?
- Property in dataclass
- What is the recommended way to include properties in dataclasses in asdict or serialization?
- Required positional arguments with dataclass properties
- Combining @dataclass and @property
- Reconciling Dataclasses And Properties In Python
and could not find a direct answer to why this simple code works fine...
class Vehicle:
def __init__(self, wheels: int = 10):
self.wheels = wheels # -> calls the setter method
@property
def wheels(self) -> int:
print("getting wheels")
return self._wheels
@wheels.setter
def wheels(self, wheels: int):
print("setting wheels to", wheels)
self._wheels = wheels
v = Vehicle()
number = v.wheels # -> calls the getter method
print(number)
# last output: 10
...but this one does not (using dataclass
):
from dataclasses import dataclass
@dataclass
class Vehicle:
wheels: int = 10
@property
def wheels(self) -> int:
print("getting wheels")
return self._wheels
@wheels.setter
def wheels(self, wheels: int):
print("setting wheels to", wheels)
self._wheels = wheels
v = Vehicle()
number = v.wheels
print(number)
# output: <property object at 0x000002042D70DDB0>
even when the official documentation of dataclass
tells explicitly in the beginning that the decorator @dataclass
adds exactly the __init__
method from the first code, i.e., this code:
@dataclass
class Vehicle:
wheels: int = 10
should add this __init__
:
def __init__(self, wheels: int = 10):
self.wheels = wheels
Is that really a bug?
Short Note:
The private attribute _wheels
is accessed only inside the property
's methods, as it should be (to isolate it).
I found in others threads (listed above) that this attribute is manipulated outside the methods, exposed as 'public', which is not desired in some cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是你的代码中的一个错误。
此代码:
将
wheels
设置为10
,然后紧接着此代码:将
wheels
设置为property
实例。@dataclass
看不到10
。你的10
不见了。注释仍然存在,因此@dataclass
创建一个wheels
字段,但字段的默认值是property
实例,而不是10
代码>.That's a bug in your code.
This code:
sets
wheels
to10
, then this code immediately after:sets
wheels
to aproperty
instance.@dataclass
can't see the10
. Your10
is gone. The annotation remains, so@dataclass
creates awheels
field, but your field's default value is aproperty
instance, not10
.