learning to code
learning to code

Reputation: 31

Modify attributes when initializing an object with dataclasses

Hi I am new to Python.
I have worked with classes before, but not with Dataclasses. In regular classes I can set a attribute of my class by using other attributes. And also using functions to modifiy the attribute when initializing an object of my class.

class Person:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = self.to_upper(last_name)
        self.full_name = f"{self.first_name}_{self.last_name}"

    def to_upper(self, some_string):
        return some_string.upper()

p1 = Person("john", "doe")
print(p1.first_name)
print(p1.last_name)
print(p1.full_name)

I was expecting to do this also with dataclasses, as I see dataclasses to be the improved version of regular classes.

from dataclasses import dataclass, field

@dataclass
class Person:
    first_name: str
    last_name: str = field(default_factory=to_upper)
    full_name: str = field(default_factory=get_fullname)

    def to_upper(self, some_string):
        return some_string.upper()

    def get_fullname(self, first_name, last_name):
        return f"{first_name}_{last_name}"

What am I missing here?

Docs for dataclasses https://docs.python.org/3/library/dataclasses.html

Upvotes: 3

Views: 6548

Answers (1)

user2853437
user2853437

Reputation: 780

As far as I understand in the moment, the __post_init__() method is used for initialise attributes with class methods.

from dataclasses import dataclass, field

@dataclass(init=True)
class Person:
    name: str = "None"
    surname: str = "Why"

    def to_upper(self,some_string):
        return some_string.lower()

    def get_fullname(self, first_name, last_name):
        return f"{first_name}_{last_name}"

    def __post_init__(self):
        self.name: str = self.to_upper(self.name)



test = Person("Bob","Alice")

See https://www.python.org/dev/peps/pep-0557/#id38

@dataclass
class C:
    a: float
    b: float
    c: float = field(init=False)

    def __post_init__(self):
        self.c = self.a + self.b

Upvotes: 5

Related Questions