Take the 2-minute tour ×

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?

share|improve this question
add comment

4 Answers

up vote 34 down vote accepted
import module
class ReplaceClass(object):
module.MyClass = ReplaceClass
share|improve this answer
+1 for being faster. just be sure that this runs before any imports that use module.MyClass –  aaronasterling Sep 21 '10 at 23:32
Being faster doesn't make more correct, but I don't really think this needs additional explanation anyway. The difference should be pretty obvious once you see how to do it. –  Glenn Maynard Sep 21 '10 at 23:37
Make sure you're the "first" to import the class. Already made references to the "old" class will not be replaced! –  Ivo van der Wijk Sep 22 '10 at 6:20
Thank you so much! Ivo made the point that actually was my mistake. I was not paying attention to the order of inclusion, which doesn't seam to matter while overloading or adding methods to the class, since they are called only when used. –  ZooKeeper Sep 22 '10 at 20:30
add comment

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.

share|improve this answer
+1 but note module.MyClass=, though it will replace the class in the module, won't replace the class in any other modules that have already done from module import MyClass. They'll have their own separate copies. Monkey-patching is bad mmkay; from module import is also bad mmkay; both at the same time is a recipe for stuff-going-wrong. –  bobince Sep 21 '10 at 23:43
@bobince, absolutely! If other parts of the code also use my detested from module import MyClass, finding and monkeying around with all of them is somewhere between "a mess" and "impossible" (gc.get_referrers can sometimes help... but not always!-). Yeah, they're both bad practice, but sometimes monkeypatching CAN be the least of evils, while creating "artificial barenames" with the from statement can always be dispensed with. –  Alex Martelli Sep 21 '10 at 23:49
This was the bit that solved my problem. –  chernevik Oct 20 '11 at 1:38
add comment

I am but an egg . . . . Perhaps it is obvious to not-newbies, but I needed the from some.package.module import module idiom.

I had to modify one method of GenerallyHelpfulClass. This failed:

import some.package.module

class SpeciallyHelpfulClass(some.package.module.GenerallyHelpfulClass): 
    def general_method(self):...

some.package.module.GenerallyHelpfulClass = SpeciallyHelpfulClass

The code ran, but didn't use the behaviors overloaded onto SpeciallyHelpfulClass.

This worked:

from some.package import module

class SpeciallyHelpfulClass(module.GenerallyHelpfulClass): 
    def general_method(self):...

module.GenerallyHelpfulClass = SpeciallyHelpfulClass

I speculate that the from ... import idiom 'gets the module', as Alex wrote, as it will be picked up by other modules in the package. Speculating further, the longer dotted reference seems to bring the module into the namespace with the import by long dotted reference, but doesn't change the module used by other namespaces. Thus changes to the import module would only appear in the name space where they were made. It's as if there were two copies of the same module, each available under slightly different references.

share|improve this answer
+1 to this because I find it more helpful to talk about extending the class that you want to patch then replacing it, rather than just extending Object and replacing it. –  sidewaysmilk Aug 30 '12 at 21:17
add comment
import some_module_name

class MyClass(object): 
     ... #copy/paste source class and update/add your logic

some_module_name.MyClass = MyClass

Its preferable not to change the name of class while replacing, because somehow someone may have referenced them using getattr - which will result in fail like below

getattr(some_module_name, 'MyClass') --> which will fail if you have replaced MyClass by ReplaceClass !

share|improve this answer
1) this will only take effect in the module performing the import: adding as foo does nothing to help. 2) your argument about getattr is not just confusing (because of your inconsistent use of names) but wrong as well and confuses the name of the class with the class itself. if I import somemodule; somemodule.someclass = someotherclass, then at a later point, in another module, getattr(somemodule, 'someclass') will return someotherclass which is exactly what OP wants. 3) copy-paste programming is ugly and error-prone. –  aaronasterling Sep 22 '10 at 5:49
@AaronMcSmooth, Agree !, now I've edited the answer, but as OP wants to replace the whole class,so I wrote copy/paste and add/update logic, because its not possible to inherit that original class as we're gonna replace it and if OP wants to update the logic only for few lines then rest code he needs to get from original source ! –  shahjapan Sep 22 '10 at 6:27
now your solution is the same as the two that have already been presented with the added blemish of a (still!) incorrect statement about getattr Also, why can't we inherit from a class that we're about to 'replace'? class A(object):pass; class B(A): pass; A = B; a = A(). –  aaronasterling Sep 22 '10 at 6:53
I think inheritance/replace will cause recursion...... –  shahjapan Sep 23 '10 at 17:51
@shajapan: what recursion? This seems to work with no problem. Is there some problem I am not aware of? –  Tom Jul 31 '12 at 10:16
add comment

Your Answer


