Function on init attribute

469 views Asked by At

I need to call a function before initialize an attribute, preferably using python3.7 dataclass, can be namedtuple also.

This code does something similar and the attributes name are just typed once, but is very confusing and I don't know how to support default values. I'm sure that there is a better and more pythonic way to do that.

from collections import namedtuple

person = {
    'name': (lambda value: value.upper()),
    'age': (lambda value: value*2),
}



class Person(namedtuple("Person", person.keys())):
    def __new__(cls, **kwargs):
        return super().__new__(cls, **{k:person[k](v) for k, v in kwargs.items() if v is not None and k in person})


l = Person(**{'name': 'gesiel', 'age': 34})
print(l)
1

There are 1 answers

0
Patrick Haugh On BEST ANSWER

The easiest way to do this is to just have a regular dataclass with a helper function that does the transforms before building the Person object.

@dataclass
class Person:
    age: int
    name: str

def make_person(age, name):
    return Person(age*2, name.upper())

person = make_person(100, 'patrick')
print(person.age, person.name)
# 200 PATRICK

Your other option would be to use Post-init processing to change the values.

@dataclass
class Person:
    age: int
    name: str
    def __post_init__(self):
        self.age  = self.age * 2
        self.name = self.name.upper()

person = Person(100, 'patrick')
print(person.age, person.name)
# 200 PATRICK