Hello All, I have some trouble using @dataclass together with @property decorator or property() function.
>From the documentation and PEP is seems that the intended behaviour of @dataclass is to be the same as normal __init__() that sets instance variables. But it seems that when using @property decorator some parts work differently when relying on default values. I'm using Pyhton 3.8.3 for this. Using the code: from dataclasses import dataclass @dataclass class Container: x: int = 30 @property def x(self) -> int: return self._x @x.setter def x(self, z: int): if z > 1: self._x = z else: raise ValueError c= Container(x=10) print(c) c= Container() print(c) output is: Container(x=10) Traceback (most recent call last): File "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-automated-testing/dataclass_example.py", line 18, in <module> c= Container() File "<string>", line 3, in __init__ File "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-automated-testing/dataclass_example.py", line 13, in x if z > 1: TypeError: '>' not supported between instances of 'property' and 'int' Code with __init__() being inserted that should be roughly the same as generated by the @dataclass decorator: @dataclass class Container: x: int = 30 def __init__(self, x:int = 30): self.x = x @property def x(self) -> int: return self._x @x.setter def x(self, z: int): if z > 1: self._x = z else: raise ValueError c= Container(x=10) print(c) c= Container() print(c) output is: Container(x=10) Container(x=30) As far as I can see, this happens because actual __init__() generated by the @dataclass decorator looks like: def __init__(self, x:int = <property object at 0x106655db0>): self.x = x I came up with a really convoluted way to work around it (just for fun, as this clearly defies the idea of dataclasses as a way to decrease boilerplate code): from dataclasses import dataclass, field def set_property(): Container.x = property(Container.get_x, Container.set_x) return 30 @dataclass class Container: x: int = field(default_factory=set_property) def get_x(self) -> int: return self._x def set_x(self, z: int): if z > 1: self._x = z else: raise ValueError c= Container(x=10) print(c) c= Container() print(c) output is: Container(x=10) Container(x=30) So, what I'm missing here? Is there some way to use field() or decorators to make property just work the same as in non-decorated class? Best regards, Ivan Ivanyuk -- https://mail.python.org/mailman/listinfo/python-list