Monkey-patch Python Class

I have a class located in a separate module that I cannot change.

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

This does not change MyClass anywhere except this file. However, if I add a method like this

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

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

How to completely replace a class?

+39
python monkeypatching
Sep 21 '10 at 23:28
source share
4 answers
 import module class ReplaceClass(object): .... module.MyClass = ReplaceClass 
+51
Sep 21 '10 at 23:30
source share

Avoid from ... import (terrible ;-) way to get names if you need qualified names most of all. When you do something right, the Python path:

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

Thus, you can neutralize the module object that you need and will work when this module is used for others. With the from ... form, you simply do not have a module object (one way to look at the glaring defect of most people using from ... ), and therefore you are clearly worse :-);

The only way I recommend using the from statement is to import the module from the package:

 from some.package.here import amodule 

so you still get the module object and will use qualified names for all the names in this module.

+27
Sep 21 '10 at 23:33
source share

I'm just an egg. ,, Maybe this is obvious to non-beginners, but I need an idiom from some.package.module import module .

I had to change one GenerallyHelpfulClass method. This failed:

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

The code worked, but did not use behavior overloaded by SpeciallyHelpfulClass.

This worked:

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

I assume that from ... import idiom 'gets a module', as Alex wrote, as it will be picked up by other modules in the package. Further, a longer dashed link appears to bring the module into the namespace with import over the long dashed link, but does not change the module used by other namespaces. Thus, changes in the import module will be displayed only in the namespace where they were made. It is as if there were two copies of the same module, each of which was available under several different links.

+9
Oct 20 2018-11-11T00:
source share
 import some_module_name class MyClass(object): ... #copy/paste source class and update/add your logic some_module_name.MyClass = MyClass 

It is preferable not to change the class name when replacing, because somehow, someone may refer to them using getattr - which will lead to failure, as shown below

getattr(some_module_name, 'MyClass') →, which will work if you replace MyClass with ReplaceClass!

+1
Sep 22 2018-10-10T00:
source share



All Articles