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 :
__init__, unlike __new__, doesn’t deal with memory references at all. self is already a valid object produced by __new__ which __init__ initializes.
You can do it the other way round for clarity:
class Person:
def __init__(self, name: str, age: int):
# Signal to whoever will read your code
# that the class is supposed to have these attributes
self.name = None
self.age = None
self.update(name=name, age=age)
def update(self, name: str, age: int):
self.name = name
self.age = age
Now __init__ isn’t called by other methods, so no confusion arises.