How to easily build a class in Python using @dataclass, @property and showing no dunder parameters in the constructor?
Let's say that I want to start with this class, which is going to grow in functionality, so let's just throw in a few attributes and keep them "private", using the preceding dunder, and make use of the @property decorator to add some business logic there or simply keep a specific level of visibility, ending with something like this: class Whatever: __attr1: int __attr2: str __attr3: list[str] @property def attr1(self) -> int: return self.__attr1 @property def attr2(self) -> str: return self.__attr2 @__attr2.setter def attr2(self, value: str) -> None: ... self.__attr2 = value def filtered_attr3(self, p1: str) -> list[str]: filtered: list[str] ... return filtered What should I do regarding the constructor? I'd like to make something Pythonic to obtain the results I intend to get. I read that it's recommended to use the @dataclass decorator to keep the process of building the __init__ method automated. But this comes with downsides: in the same way that I try to hide the attributes from outside the class, this decorator is going to take its name and show it as a constructor parameter. For such a case I read about backing fields, declaring the attributes duplicate, but without the "__" prefix and making use of the typing.field method with this sentence for every attribute: ... attr1: int __attr1 = field(init=False, repr=False) ... But if I want to spare myself the trouble of typing the __init__ method it's not to change it for a far worse boilerplate code. Otherwise I can't find any other alternatives that comply with all the points previously mentioned. What would be considered better? @dataclass + __attr + @property @dataclass + attr (instead of __attr) + @property __init__ + __attr + @property Go the simple way with __init__ and dispose of everything else mentioned. Any other alternative I didn't think of? I think that that the best option could be using both annotations and dispose of the "private" attributes, since methods with @property decorator before them would trigger before letting access to the attributes directly, thus leaving the automatic constructor parameters underscore-free as well.
Let's say that I want to start with this class, which is going to grow in functionality, so let's just throw in a few attributes and keep them "private", using the preceding dunder, and make use of the @property
decorator to add some business logic there or simply keep a specific level of visibility, ending with something like this:
class Whatever:
__attr1: int
__attr2: str
__attr3: list[str]
@property
def attr1(self) -> int:
return self.__attr1
@property
def attr2(self) -> str:
return self.__attr2
@__attr2.setter
def attr2(self, value: str) -> None:
...
self.__attr2 = value
def filtered_attr3(self, p1: str) -> list[str]:
filtered: list[str]
...
return filtered
What should I do regarding the constructor? I'd like to make something Pythonic to obtain the results I intend to get.
I read that it's recommended to use the @dataclass
decorator to keep the process of building the __init__
method automated. But this comes with downsides: in the same way that I try to hide the attributes from outside the class, this decorator is going to take its name and show it as a constructor parameter. For such a case I read about backing fields, declaring the attributes duplicate, but without the "__" prefix and making use of the typing.field
method with this sentence for every attribute:
...
attr1: int
__attr1 = field(init=False, repr=False)
...
But if I want to spare myself the trouble of typing the __init__
method it's not to change it for a far worse boilerplate code. Otherwise I can't find any other alternatives that comply with all the points previously mentioned.
What would be considered better?
@dataclass
+__attr
+@property
@dataclass
+attr
(instead of__attr
) +@property
__init__
+__attr
+@property
- Go the simple way with
__init__
and dispose of everything else mentioned. - Any other alternative I didn't think of?
I think that that the best option could be using both annotations and dispose of the "private" attributes, since methods with @property
decorator before them would trigger before letting access to the attributes directly, thus leaving the automatic constructor parameters underscore-free as well.