'Updating an instance of an object with the __init__ method

Reusing the __init__ method to change attributes' values

Python 3.10 on Windows 64bit

Let's say I have a class that has an update method which calls the __init__ method. The update method is created to avoid multiple line assignments of the attributes.

class Person:
     def __init__(self, name: str, age: int):
         self.name = name
         self.age = age

     def update(self, **attributes):
         self.__init__(**attributes)

Object instantiation:

p = Person(name="Alex", age=32)
print(p.name, p.age)

>> Alex 32

Object reference before:

print(p)

>> <__main__.Person object at 0x0000028B4ED949A0>

Calling for the update method:

p.update(name="Sam", age=80)
print(p.name, p.age)

>> Sam 80

Object reference after:

print(p)

>> <__main__.Person object at 0x0000028B4ED949A0>

Clearly, the reference hasn't changed!

Is this safe? Is there a chance where the object reference in memory gets changed?

Obviously the actual use of this is for large objects that has multiple parameters and get frequently modified at once as internal reactions. Some parameters are optional and don't get modified.

If I don't do it like this, I would have to write a cascade of if-else statements which I don't want to. :)



Solution 1:[1]

in addition to ForceBru's answer if wanted

class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def update(self, **attributes):
        for attribute, value in attributes.items():
            if hasattr(self,attribute):
                setattr(self, attribute, value)
            else:
                raise AttributeError(f'{self.__name__} has no attribute: {attribute}')
        
x = Person(name='Henry',age=12)
print(f'name={x.name}, age={x.age}')
x.update(name='Joe')
print(f'name={x.name}, age={x.age}')
x.update(name='Kyle',age=20)
print(f'name={x.name}, age={x.age}')

gives output

name=Henry, age=12
name=Joe, age=12
name=Kyle, age=20

this is just template (you may have other specific behavior that want for example dont want users to overwrite attributes start with _, etc).

I will say ultimately ForceBru's is nice in terms of linters, intellisense, etc, so can use what works for you

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1