Q: Is there a way to alter a method of an existing object in Python (3.6)? (By "method" I mean a function that is passed self
as an argument.)
Example
Let's say I have a class Person
having some very useful method SayHi()
:
class Person(object):
Cash = 100
def HasGoodMood(self):
return self.Cash > 10
def SayHi(self):
if self.HasGoodMood():
print('Hello!')
else:
print('Hmpf.')
>>> joe = Person()
>>> joe.SayHi()
Hello!
As you can see, the response of the person depends on their current mood computed by the method HasGoodMood()
. A default person has good mood whenever they have more than 10$ cash on them.
I can easily create a person who does not care about the money and is happy all the time:
>>> joe.HasGoodMood = lambda: True
>>> joe.SayHi()
Hello!
>>> joe.Cash = 0
>>> joe.SayHi()
Hello!
Cool. Notice how Python knows that when using the original implementation of HasGoodMood
, it passes silently self
as the first argument, but if I change it to lambda: True
, it calls the function with no arguments. The problem is: What if I want to change the default HasGoodMood
for another function which would also accept self
as a parameter?
Let's continue our example: what if I want to create a greedy Person
who is only happy if they have more than 100$ on them? I would like to do something like:
>>> greedy_jack = Person()
>>> greedy_jack.HasGoodMood = lambda self: self.Cash > 100
TypeError: <lambda>() missing 1 required positional argument: 'self'
Unfortunately, this does not work. Is there some other way to change a method?
Disclaimer: The above example is just for demonstration purposes. I know that I could use inheritance or keep a cash threshold as a property of the Person
. But that is not the point of the question.