It sure does work:
from dataclasses import dataclass
@dataclass
class Test:
_name: str="schbell"
@property
def name(self) -> str:
return self._name
@name.setter
def name(self, v: str) -> None:
self._name = v
t = Test()
print(t.name) # schbell
t.name = "flirp"
print(t.name) # flirp
print(t) # Test(_name='flirp')
In fact, why should it not? In the end, what you get is just a good old class, derived from type:
print(type(t)) # <class '__main__.Test'>
print(type(Test)) # <class 'type'>
Maybe that's why properties are nowhere mentioned specifically. However, the PEP-557's Abstract mentions the general usability of well-known Python class features:
Answer from shmee on Stack OverflowBecause Data Classes use normal class definition syntax, you are free to use inheritance, metaclasses, docstrings, user-defined methods, class factories, and other Python class features.
It sure does work:
from dataclasses import dataclass
@dataclass
class Test:
_name: str="schbell"
@property
def name(self) -> str:
return self._name
@name.setter
def name(self, v: str) -> None:
self._name = v
t = Test()
print(t.name) # schbell
t.name = "flirp"
print(t.name) # flirp
print(t) # Test(_name='flirp')
In fact, why should it not? In the end, what you get is just a good old class, derived from type:
print(type(t)) # <class '__main__.Test'>
print(type(Test)) # <class 'type'>
Maybe that's why properties are nowhere mentioned specifically. However, the PEP-557's Abstract mentions the general usability of well-known Python class features:
Because Data Classes use normal class definition syntax, you are free to use inheritance, metaclasses, docstrings, user-defined methods, class factories, and other Python class features.
A solution with minimal additional code and no hidden variables is to override the __setattr__ method to do any checks on the field:
@dataclass
class Test:
x: int = 1
def __setattr__(self, prop, val):
if prop == "x":
self._check_x(val)
super().__setattr__(prop, val)
@staticmethod
def _check_x(x):
if x <= 0:
raise ValueError("x must be greater than or equal to zero")
How does Python interpret whether a dataclass attribute is an instance attribute or a class attribute?
Allow overriding (abstract) properties with fields - Ideas - Discussions on Python.org
When to use @cached_property over @property @cache?
Reconciling Dataclasses And Properties In Python - Florimond Manca
Videos
I read on SO about the below example:
# Case 1
class Foo:
x: int
# At this point, x has no value, so doesn't actually exist as a variable.
# Case 2
class Foo:
y: int = 3
# You are creating both a class variable and an annotationIs dataclass an exception? As a class attribute in a dataclass must be annotated with ClassVar.
In a dataclass, a type-annotated attribute with a default value provided, does a class attribute
As I've gotten comfortable with dataclasses, I've started stretching the limits of how they're conventionally meant to be used. Except for a few rarely relevant scenarios, they provide feature-parity with regular classes, and they provide a strictly-nicer developer experience IMO. All the things they do intended to clean up a 20-property, methodless class also apply to a 3-input class with methods.
E.g. Why ever write something like the top when the bottom arguably reads cleaner, gives a better type hint, and provides a better default __repr__?