Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monkey-patch Python class

I've got a class, located in a separate module, which I can't change.

from module import MyClass  class ReplaceClass(object)   ...  MyClass = ReplaceClass 

This doesn't change MyClass anywhere else but this file. However if I'll add a method like this

def bar():    print 123  MyClass.foo = bar 

this will work and foo method will be available everywhere else.

How do I replace the class completely?

like image 497
ZooKeeper Avatar asked Sep 21 '10 23:09

ZooKeeper


People also ask

What is class monkey patching?

Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. A monkey patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.)

What is monkey patching concept in Python?

In Python, the term monkey patch only refers to dynamic modifications of a class or module at runtime, motivated by the intent to patch existing third-party code as a workaround to a bug or feature which does not act as you desire.

Is monkey patching a good practice?

But you should never consider this a standard technique and build monkey patch upon monkey patch. This is considered bad because it means that an object's definition does not completely or accurately describe how it actually behaves.


2 Answers

import module class ReplaceClass(object):     .... module.MyClass = ReplaceClass 
like image 70
Glenn Maynard Avatar answered Sep 23 '22 17:09

Glenn Maynard


Avoid the from ... import (horrid;-) way to get barenames when what you need most often are qualified names. Once you do things the right Pythonic way:

import module  class ReplaceClass(object): ...  module.MyClass = ReplaceClass 

This way, you're monkeypatching the module object, which is what you need and will work when that module is used for others. With the from ... form, you just don't have the module object (one way to look at the glaring defect of most people's use of from ...) and so you're obviously worse off;-);

The one way in which I recommend using the from statement is to import a module from within a package:

from some.package.here import amodule 

so you're still getting the module object and will use qualified names for all the names in that module.

like image 20
Alex Martelli Avatar answered Sep 22 '22 17:09

Alex Martelli