Messing With Self
First, the boring case where classes are classes and instances are instances.
Nothing new there. But what is with self? What's so special about it? Let's rebel. Everywhere self is shall be replaced with the word her.
It turns out self is not that special after all. It's just a convention for distinguishing the instance of a class from the class itself. Strictly speaking, self could be this or alice or bob or the gender pronoun of your choice. Politically correct Python for the win!
But seriously, did you ever stop to think about how strange it is when it comes to self and how calls method calls actually work?
ob1.say_stuff()
The ob1 in this case looks like it's the self that say_stuff refers to. Let's twist that call around a little.
Okay, so there's that. Now, be sure of this. The self term absolutely refers to an instance of the class it's being used in ... right? You have to wonder sometimes.
So much for that idea. At any rate, it's safe to say we've abused self enough for now.
Time For Some Actual Monkey Patching
Here, we play a game about filling in the missing pieces. What if we had a starting class without an __init__. To make it more interesting, let's NOT set up another class through which to provide instance variables. Something like this.
And who would have thunk. We can actually make this work in spite of the fact that the instance was born without a msg. Time for some setattr() surgery.
Oh heck, let's go gangbusters and just monkey patch a bare naked class together. Here's what that ends up looking like. Heck, we'll do up the instance too. Here it goes.
What else to play with? Ooo, I know!
Direct Assignments And Dictionaries
Python classes seem mutable enough. Maybe you can even directly assign to one method to take the place of the original.
Awesome! That opens up quite a few possibilities right there.
Okay, one last thought. Python classes and instances have these things called dictionaries that dwell beneath the surface. Dictionaries represent methods and attributes.
Now, here's an idea. say_stuff isn't a member of the instance dictionary. It's a member of the class that the instance is based on. If there no say_stuff in the instance? No problem. Just look it up in the dictionary of the class instead.
Sooooo, what if we exploited the instance dictionary to subvert that expectation.
Now, here's an idea. say_stuff isn't a member of the instance dictionary. It's a member of the class that the instance is based on. If there no say_stuff in the instance? No problem. Just look it up in the dictionary of the class instead.
Sooooo, what if we exploited the instance dictionary to subvert that expectation.
And yes, that setattr trick that's commented out there works too. And there are other things to say and do with these underlying dictionaries too. However, exploring much further requires diving into the mysterious world of metaclasses. Let's not go there.... unless you really want to. ;-)
Well That Was Fun!
This is definitely not something you'd likely want to do with any REAL project unless you absolutely had to. Overuse of monkey patching can make things messy and confusing. At any rate, I hope you enjoyed this read. Have a great week.