ā¹ļø Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 5.2 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://mgarod.medium.com/dynamically-add-a-method-to-a-class-in-python-c49204b85bd6 |
| Last Crawled | 2025-11-01 19:09:13 (5 months ago) |
| First Indexed | 2021-03-16 03:08:56 (5 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Dynamically Add a Method to a Class in Python | by Michael Garod | Medium |
| Meta Description | Dynamically Add a Method to a Class in Python I often use ipython on the command line to create minimal examples of things I want to try. When I need to make things related to a class, I often find ⦠|
| Meta Canonical | null |
| Boilerpipe Text | I often use ipython on the command line to create minimal examples of things I want to try. When I need to make things related to a class, I often find myself making a class, using it for a while, then when I need to add more methods to the class or edit a line, I have to hit up-arrow until I get back to the line with the class declaration, then resubmit the entire class to the interpreter, when all I wanted to do was add method foo to class A . So I thought to myself, how can I make the following code work? class A: pass a = A() def foo(): print('hello world!') ### PYTHON MAGIC GOES HERE ### a.foo() # hello world! After perusing such stack overflow posts such as https://stackoverflow.com/questions/17929543/how-can-i-dynamically-create-class-methods-for-a-class-in-python , I stumbled upon the builtin setattr ( https://docs.python.org/3/library/functions.html#setattr ) which accomplishes the task. class A: pass a = A() def foo(self): # Have to add self since this will become a method print('hello world!') setattr(A, 'foo', foo) a.foo() # hello world! Indeed, the above does work. However, I found this solution rather inelegant. This use case begs for some reusable bit of code, such that I can add any function to any existing class. What I want is to decorate any function so that it becomes a method to the class. I want the following code to work. class A: pass a = A() @add_method(A) def foo(): print('hello world!') a.foo() # hello world! I want the burden of the work to be done by the decorator and not force the programmer to have to add self to functions (which would render the functions unusable until bound to a class), and I want to simplify the use of setattr which always requires a name and object to be bound which can be a pain for refactoring and redundant since the function itself knows its __name__ . After following this line of thought down the rabbit hole for about an hour, here is the result. You can copy paste this into a file and try it out for yourself. The add_method decorator does all the heavy lifting. Both functions foo and bar are still valid functions after they are bound as methods. Iām not sure how useful this will ever be (probably not useful at all). This is just the kind of thing that I like to experiment in with ipython . |
| Markdown | [Sitemap](https://mgarod.medium.com/sitemap/sitemap.xml)
[Open in app](https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Fc49204b85bd6&~feature=LoOpenInAppButton&~channel=ShowPostUnderUser&~stage=mobileNavBar&source=post_page---top_nav_layout_nav-----------------------------------------)
Sign up
[Sign in](https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fmgarod.medium.com%2Fdynamically-add-a-method-to-a-class-in-python-c49204b85bd6&source=post_page---top_nav_layout_nav-----------------------global_nav------------------)
[Medium Logo](https://medium.com/?source=post_page---top_nav_layout_nav-----------------------------------------)
[Write](https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---top_nav_layout_nav-----------------------new_post_topnav------------------)
[Search](https://medium.com/search?source=post_page---top_nav_layout_nav-----------------------------------------)
Sign up
[Sign in](https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fmgarod.medium.com%2Fdynamically-add-a-method-to-a-class-in-python-c49204b85bd6&source=post_page---top_nav_layout_nav-----------------------global_nav------------------)

Top highlight
# Dynamically Add a Method to a Class in Python
[](https://mgarod.medium.com/?source=post_page---byline--c49204b85bd6---------------------------------------)
[Michael Garod](https://mgarod.medium.com/?source=post_page---byline--c49204b85bd6---------------------------------------)
Follow
2 min read
Ā·
Oct 26, 2017
483
14
[Listen](https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2Fplans%3Fdimension%3Dpost_audio_button%26postId%3Dc49204b85bd6&operation=register&redirect=https%3A%2F%2Fmgarod.medium.com%2Fdynamically-add-a-method-to-a-class-in-python-c49204b85bd6&source=---header_actions--c49204b85bd6---------------------post_audio_button------------------)
Share
I often use `ipython` on the command line to create minimal examples of things I want to try. When I need to make things related to a class, I often find myself making a class, using it for a while, then when I need to add more methods to the class or edit a line, I have to hit up-arrow until I get back to the line with the class declaration, then resubmit the entire class to the interpreter, when all I wanted to do was add method `foo` to `class A` .
So I thought to myself, how can I make the following code work?
```
class A:
pass
a = A()def foo():
print('hello world!')### PYTHON MAGIC GOES HERE ###a.foo() # hello world!
```
After perusing such stack overflow posts such as <https://stackoverflow.com/questions/17929543/how-can-i-dynamically-create-class-methods-for-a-class-in-python>, I stumbled upon the builtin`setattr` (<https://docs.python.org/3/library/functions.html#setattr>) which accomplishes the task.
```
class A:
pass
a = A()def foo(self): # Have to add self since this will become a method
print('hello world!')setattr(A, 'foo', foo)a.foo() # hello world!
```
Indeed, the above does work. However, I found this solution rather inelegant.
## Get Michael Garodās stories in your inbox
Join Medium for free to get updates from this writer.
Subscribe
Subscribe
This use case begs for some reusable bit of code, such that I can add any function to any existing class. What I want is to **decorate** any function so that it becomes a method to the class. I want the following code to work.
```
class A:
pass
a = A()@add_method(A)
def foo():
print('hello world!')a.foo() # hello world!
```
I want the burden of the work to be done by the decorator and not force the programmer to have to add `self` to functions (which would render the functions unusable until bound to a class), and I want to simplify the use of `setattr` which always requires a name and object to be bound which can be a pain for refactoring and redundant since the function itself knows its `__name__`.
After following this line of thought down the rabbit hole for about an hour, here is the result.
You can copy paste this into a file and try it out for yourself.
The `add_method` decorator does all the heavy lifting. Both functions `foo` and `bar` are still valid functions after they are bound as methods.
Iām not sure how useful this will ever be (probably not useful at all). This is just the kind of thing that I like to experiment in with `ipython`.
[Python Programming](https://medium.com/tag/python-programming?source=post_page-----c49204b85bd6---------------------------------------)
[Python](https://medium.com/tag/python?source=post_page-----c49204b85bd6---------------------------------------)
[Object Oriented](https://medium.com/tag/object-oriented?source=post_page-----c49204b85bd6---------------------------------------)
[Python Decorators](https://medium.com/tag/python-decorators?source=post_page-----c49204b85bd6---------------------------------------)
483
483
14
[](https://mgarod.medium.com/?source=post_page---post_author_info--c49204b85bd6---------------------------------------)
[](https://mgarod.medium.com/?source=post_page---post_author_info--c49204b85bd6---------------------------------------)
Follow
[Written by Michael Garod](https://mgarod.medium.com/?source=post_page---post_author_info--c49204b85bd6---------------------------------------)
[27 followers](https://mgarod.medium.com/followers?source=post_page---post_author_info--c49204b85bd6---------------------------------------)
Ā·[1 following](https://mgarod.medium.com/following?source=post_page---post_author_info--c49204b85bd6---------------------------------------)
Software Engineer
Follow
## Responses (14)

Write a response
[What are your thoughts?](https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fmgarod.medium.com%2Fdynamically-add-a-method-to-a-class-in-python-c49204b85bd6&source=---post_responses--c49204b85bd6---------------------respond_sidebar------------------)
Cancel
Respond
[](https://medium.com/@piperthunstrom?source=post_page---post_responses--c49204b85bd6----0-----------------------------------)
[Piper Thunstrom](https://medium.com/@piperthunstrom?source=post_page---post_responses--c49204b85bd6----0-----------------------------------)
[Nov 29, 2017](https://medium.com/@piperthunstrom/dont-know-why-you-wouldn-t-use-a-foo-staticmethod-foo-for-this-use-case-85417842df5b?source=post_page---post_responses--c49204b85bd6----0-----------------------------------)
```
Donāt know why you wouldnāt use `A.foo = staticmethod(foo)` for this use case.
```
41
Reply
[](https://medium.com/@feelus.kov?source=post_page---post_responses--c49204b85bd6----1-----------------------------------)
[Š¤ŠøŠ»Ń Š£ŃŠŗŠ¾Š²](https://medium.com/@feelus.kov?source=post_page---post_responses--c49204b85bd6----1-----------------------------------)
[Dec 24, 2019](https://medium.com/@feelus.kov/def-wrapper-self-args-kwargs-238b687f1213?source=post_page---post_responses--c49204b85bd6----1-----------------------------------)
```
>def wrapper(self, *args, **kwargs):> return func(*args, **kwargs)should replace with>def wrapper(self, *args, **kwargs):> return func(self,*args, **kwargs)
```
4
1 reply
Reply
[](https://medium.com/@ruben.m.menke?source=post_page---post_responses--c49204b85bd6----2-----------------------------------)
[Ruben Menke](https://medium.com/@ruben.m.menke?source=post_page---post_responses--c49204b85bd6----2-----------------------------------)
[Aug 1, 2018](https://medium.com/@ruben.m.menke/i-have-experimented-with-this-too-and-have-not-got-such-an-elegant-method-as-you-did-so-this-was-cc23a1022247?source=post_page---post_responses--c49204b85bd6----2-----------------------------------)
```
I have experimented with this too and have not got such an elegant method as you did so this was super helpfull for me (and my colleagues). I use it to add functionality to pandas which is project / work specific.
```
2
Reply
See all responses
## More from Michael Garod

[](https://mgarod.medium.com/?source=post_page---author_recirc--c49204b85bd6----0---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
[Michael Garod](https://mgarod.medium.com/?source=post_page---author_recirc--c49204b85bd6----0---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
[The Curious Case of Failing Over in KubernetesNo matter what your use case or workload, when working in a distributed environment like Kubernetes, it is important to remember thatā¦](https://mgarod.medium.com/the-curious-case-of-failing-over-in-kubernetes-fcd16bc9a94d?source=post_page---author_recirc--c49204b85bd6----0---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
Oct 27, 2018
[A clap icon 37A response icon 2](https://mgarod.medium.com/the-curious-case-of-failing-over-in-kubernetes-fcd16bc9a94d?source=post_page---author_recirc--c49204b85bd6----0---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)

[](https://mgarod.medium.com/?source=post_page---author_recirc--c49204b85bd6----1---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
[Michael Garod](https://mgarod.medium.com/?source=post_page---author_recirc--c49204b85bd6----1---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
[A Workaround for Private Scope in Python ClassesIāve always wondered about private variables in Python. Iām still pretty sure itās not possible (please comment if you have more knowledgeā¦](https://mgarod.medium.com/a-workaround-for-private-scope-in-python-classes-bf8100927ab1?source=post_page---author_recirc--c49204b85bd6----1---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
Nov 6, 2017
[A clap icon 4](https://mgarod.medium.com/a-workaround-for-private-scope-in-python-classes-bf8100927ab1?source=post_page---author_recirc--c49204b85bd6----1---------------------03fe3b48_b82c_42b0_aca5_b7ef64fe65f3--------------)
[See all from Michael Garod](https://mgarod.medium.com/?source=post_page---author_recirc--c49204b85bd6---------------------------------------)
## Recommended from Medium

[](https://python.plainenglish.io/?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
In
[Python in Plain English](https://python.plainenglish.io/?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
by
[Rohan Mistry](https://medium.com/@rohanmistry231?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[š§© Dependency Injection in Python: A Complete Guide to Cleaner, Scalable CodeWhen you hear āDependency Injectionā (DI), your mind might jump to complex enterprise frameworks in Java or C\#. But Python, with itsā¦](https://medium.com/@rohanmistry231/dependency-injection-in-python-a-complete-guide-to-cleaner-scalable-code-9c6b38d1b924?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
May 11
[A clap icon 121A response icon 1](https://medium.com/@rohanmistry231/dependency-injection-in-python-a-complete-guide-to-cleaner-scalable-code-9c6b38d1b924?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)

[](https://generativeai.pub/?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
In
[Generative AI](https://generativeai.pub/?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
by
[Adham Khaled](https://medium.com/@adhamhidawy?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Stanford Just Killed Prompt Engineering With 8 Words (And I Canāt Believe It Worked)ChatGPT keeps giving you the same boring response? This new technique unlocks 2Ć more creativity from ANY AI model ā no training requiredā¦](https://medium.com/@adhamhidawy/stanford-just-killed-prompt-engineering-with-8-words-and-i-cant-believe-it-worked-8349d6524d2b?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
Oct 20
[A clap icon 13.3KA response icon 290](https://medium.com/@adhamhidawy/stanford-just-killed-prompt-engineering-with-8-words-and-i-cant-believe-it-worked-8349d6524d2b?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)

[](https://medium.com/the-pythonworld?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
In
[The Pythonworld](https://medium.com/the-pythonworld?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
by
[Aashish Kumar](https://medium.com/@aashishkumar_77032?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[10 Python Concepts That Took Me Years to Understand ā Until I Saw These ExamplesSometimes one example can do more than a hundred explanations. Here are the ones that finally made things click for me.](https://medium.com/@aashishkumar_77032/10-python-concepts-that-took-me-years-to-understand-until-i-saw-these-examples-8ee670212c33?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
Oct 19
[A clap icon 502A response icon 8](https://medium.com/@aashishkumar_77032/10-python-concepts-that-took-me-years-to-understand-until-i-saw-these-examples-8ee670212c33?source=post_page---read_next_recirc--c49204b85bd6----0---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)

[](https://codingplainenglish.medium.com/?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Abhinav](https://codingplainenglish.medium.com/?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Docker Is Dead ā And Itās About TimeDocker changed the game when it launched in 2013, making containers accessible and turning āDockerize itā into a developer catchphrase.](https://codingplainenglish.medium.com/docker-is-dead-and-its-about-time-b457d14b0a72?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
Jun 9
[A clap icon 7.1KA response icon 203](https://codingplainenglish.medium.com/docker-is-dead-and-its-about-time-b457d14b0a72?source=post_page---read_next_recirc--c49204b85bd6----1---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)

[](https://medium.com/@nabeel.ar1?source=post_page---read_next_recirc--c49204b85bd6----2---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Nabeel Abdul Rahman](https://medium.com/@nabeel.ar1?source=post_page---read_next_recirc--c49204b85bd6----2---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Deep Learning Demystified: An Interactive Hands-On Journey from Zero to IntuitionPerfect for beginners ā no code, just concepts and visual intuition.](https://medium.com/@nabeel.ar1/deep-learning-demystified-an-interactive-hands-on-journey-from-zero-to-intuition-e51d1a1c7a92?source=post_page---read_next_recirc--c49204b85bd6----2---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
Jul 18

[](https://tosny.medium.com/?source=post_page---read_next_recirc--c49204b85bd6----3---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[Tosny](https://tosny.medium.com/?source=post_page---read_next_recirc--c49204b85bd6----3---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[7 Websites I Visit Every Day in 2025If there is one thing I am addicted to, besides coffee, it is the internet.](https://tosny.medium.com/7-websites-i-visit-every-day-in-2025-ef54332a2003?source=post_page---read_next_recirc--c49204b85bd6----3---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
Sep 23
[A clap icon 6.3KA response icon 220](https://tosny.medium.com/7-websites-i-visit-every-day-in-2025-ef54332a2003?source=post_page---read_next_recirc--c49204b85bd6----3---------------------8b84b531_2da6_4550_8dfe_edcfa3294c62--------------)
[See more recommendations](https://medium.com/?source=post_page---read_next_recirc--c49204b85bd6---------------------------------------)
[Help](https://help.medium.com/hc/en-us?source=post_page-----c49204b85bd6---------------------------------------)
[Status](https://status.medium.com/?source=post_page-----c49204b85bd6---------------------------------------)
[About](https://medium.com/about?autoplay=1&source=post_page-----c49204b85bd6---------------------------------------)
[Careers](https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----c49204b85bd6---------------------------------------)
[Press](mailto:pressinquiries@medium.com)
[Blog](https://blog.medium.com/?source=post_page-----c49204b85bd6---------------------------------------)
[Privacy](https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----c49204b85bd6---------------------------------------)
[Rules](https://policy.medium.com/medium-rules-30e5502c4eb4?source=post_page-----c49204b85bd6---------------------------------------)
[Terms](https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----c49204b85bd6---------------------------------------)
[Text to speech](https://speechify.com/medium?source=post_page-----c49204b85bd6---------------------------------------) |
| Readable Markdown | null |
| Shard | 77 (laksa) |
| Root Hash | 13179037029838926277 |
| Unparsed URL | com,medium!mgarod,/dynamically-add-a-method-to-a-class-in-python-c49204b85bd6 s443 |