Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Monkey patching replace existing function definition in a class?

I know how fierce the SO community is so I'll try my best to keep the question minimal, complete and verifiable.

What I simply want to know is can monkey patching be used to replace the definition of an existing function?

for example:

class A():

    def foo():
       print '2'

def foo():
    print '5'

A.foo = foo

This way doesn't seem to work also as to why I don't just add a new function instead of replacing an existing one, I call these functions in other classes and it is my understanding that monkey patching adds those functions at run-time and I need my python code to run on an Apache spark server which throws an error deeming the calls to that function unreferenced.

So please be nice and help me out or suggest a work around. Thanks.

Edit: The goal of the code is to print 5 when A.foo is called.

like image 410
Vivek Shankar Avatar asked Dec 04 '25 15:12

Vivek Shankar


1 Answers

Your only problem is that you aren't defining foo correctly in the first place. It needs to take an explicit argument for the instance calling it.

class A(object):
    def __init__(self)
        self.x = 2

    def foo(self):
        print(self.x)

def foo(this):
    print(this.x + 3)

A.foo = foo

a = A()
a.foo()  # outputs 5 in Python 2 and Python 3

In a very real sense, monkey patching is how classes are created in the first place. A class statement is almost just syntactic sugar for the following code:

def foo(self):
    print(self.x)
A = type('A', (object,), {'foo': foo})
del foo

It's not too much of a simplification to image the definition of type being something like

def type(name, bases, d):
    new_class = magic_function_to_make_a_class()
    new_class.name = name
    new_class.bases = bases
    for k, v in d.items():
        setattr(new_class, k, v)
    return new_class
like image 170
chepner Avatar answered Dec 07 '25 05:12

chepner