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.

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.