How to call the original method when it is monkey-patched?
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Take control of your privacy with Proton's trusted, Swiss-based, secure services.
Choose what you need and safeguard your digital life:
Mail: https://go.getproton.me/SH1CU
VPN: https://go.getproton.me/SH1DI
Password Manager: https://go.getproton.me/SH1DJ
Drive: https://go.getproton.me/SH1CT
Music by Eric Matyas
https://www.soundimage.org
Track title: Magic Ocean Looping
--
Chapters
00:00 How To Call The Original Method When It Is Monkey-Patched?
01:40 Answer 1 Score 1
02:02 Answer 2 Score 2
02:11 Answer 3 Score 23
02:36 Accepted Answer Score 6
03:16 Thank you
--
Full question
https://stackoverflow.com/questions/8726...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #oop #python3x #monkeypatching #overriding
#avk47
ANSWER 1
Score 23
This is what we call a 'decorator' pattern. Replace the original reassignment of name to have it call a function instead, which takes the original. It then returns a new function.
def name_decorator(method):
def decorate_name(self=None):
return stuff + method(self)
return decorate_name
A.name = name_decorator(A.name)
Later, calling A.name will call decorate_name with self as the current instance and method will be available to it which points to the function at the time of the reassignment.
ACCEPTED ANSWER
Score 6
Here's a full example of what I was hinting at. Feel free to yell at me and have me merge my answers, or downvote one or whatever, just easier to provide an alternative as a new answer. I'll let the code do the talking instead of poorly explaining it. :)
## Some shared class that is used all over the place and needs to be patched.
class A(object):
def __init__(self):
self.firstname = 'Bob'
# Print my first name.
def name(self):
return self.firstname
# Use this to allow patching arbitrary methods...
@classmethod
def patch(cls, func_name):
def patch_by_name(new_func):
old_func = getattr(cls, func_name)
def patched_func(self):
return new_func(self, old_func)
setattr(cls, func_name, patched_func)
return patch_by_name
## Some other area of the code where you want to throw in a patch
class PatchedA(A): # doesn't need to subclass, but comes in handy sometimes
@A.patch('name')
def name(self, orig_func):
return 'I am ' + orig_func(self) + 'McWizwaz'
print 'Who are you, A class?'
print A().name() # prints 'I am Bob McWizwaz'
ANSWER 3
Score 2
class ABase(object):
def name(self):
pass
class A(object):
pass
class AExtension(ABase):
def name(self):
return ABase.name(self)
A.name = AExtension.name
ANSWER 4
Score 1
One option that might not always be the best in a language like Python is to use the @override decorator from this non-standard package. But this is a viable option only if your two functions work on different types or different number of arguments. Other than that, there's not much you can do, besides renaming your function.