Add a method to an existing object instance in Python

avatar

Borislav Hadzhiev

Last updated: Jun 22, 2022

banner

Photo from Unsplash

Add a method to an existing object instance in Python #

Use the types.MethodType function to add a method to an existing object instance, e.g. my_inst.increase_salary = types.MethodType(increase_salary, my_inst). The MethodType function will bind the method to the instance.

main.py
import types class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = types.MethodType(increase_salary, alice) print(alice.increase_salary()) # 👉️ 200 print(alice.increase_salary()) # 👉️ 300

When adding a method to an existing object, we have to take care of binding it to the object, so that the instance is passed as the first argument when the method is called

main.py
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) def increase_salary(self): self.salary += 100 return self.salary print(increase_salary) # <function increase_salary at 0x7f6b939ffd90> print(alice.__init__) # <bound method Employee.__init__ of <__main__.Employee object at 0x7f6b938f7100>>

However, if we add th method on the class, we don't have to take care of binding it and it will be an unbound method, that is available on all previously created instances.

main.py
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary Employee.increase_salary = increase_salary print(Employee.increase_salary) # <function increase_salary at 0x7fb813bf7d90> print(alice.increase_salary()) # 👉️ 200 print(bob.increase_salary()) # 👉️ 200

When the method is added directly on the existing object instance, it is only available on the specific instance.

main.py
import types class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = types.MethodType(increase_salary, alice) # <bound method increase_salary of <__main__.Employee object at 0x7f6edb29f4c0>> print(alice.increase_salary) print(alice.increase_salary()) # 👉️ 200 # ⛔️ AttributeError: 'Employee' object has no attribute 'increase_salary' print(bob.increase_salary())

An alternative to using the MethodType function is to use a descriptor to bind the method to the class instance.

main.py
class Employee(): def __init__(self, name, salary): self.name = name self.salary = salary alice = Employee('Alice', 100) bob = Employee('Bob', 100) def increase_salary(self): self.salary += 100 return self.salary alice.increase_salary = increase_salary.__get__(alice) print(alice.increase_salary()) # 👉️ 200 print(alice.increase_salary()) # 👉️ 300 # <bound method increase_salary of <__main__.Employee object at 0x7f31cc8174c0>> print(increase_salary.__get__(alice))

We used the __get__() method on the function.

Functions have a __get__() method so they can be converted to a method when accessed as attributes.

This helps us convert the increase_salary function to a method that is bound to the specific class instance.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.