Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add a method to a class from a third-party Python module without editing the original module

I'm using the Basemap object from basemap module in the matplotlib toolkit (mpl_toolkits.basemap.Basemap). In basemap's __init__.py file (i.e. the mpl_toolkits.basemap.__init__ module), a method drawparallels is defined which draws latitudes on the map. I aim to duplicate that method to make a new method called drawmlat, making some adjustments in order to plot magnetic latitudes instead of geographic latitudes.

Ideally, I want the new drawmlat to be equivalent to the original drawparallel (a bound method of the instances of Basemap that I can call with using BasemapInstance.drawmlats()), and I do not want to modify the original file. How would I accomplish this?

I have tried variations of the "recipe" MyObj.method = MethodType(new_method, None, MyObj), but without placing anything in the original source file, the new method does not have access to globals etc. from the Basemap module (e.g. defined in its __init__.py).

If it seems I have misunderstood something, I probably have - I am more or less completely new to object-oriented programming.

like image 677
cmeeren Avatar asked Oct 28 '25 02:10

cmeeren


1 Answers

Python is highly modifiable. Just add your function to the class:

from mpl_toolkits.basemap import Basemap


def drawmlat(self, arg1, arg2, kw=something):
    pass

Basemap.drawmlat = drawmlat

Now the Basemap class has a drawmlat method; call it on instances and self will be bound to the instance object. When looking up the method on instances, the function will automatically be bound as a method for you.

Anything defined in the Basemap.__init__ method that you need to care about are attributes on self.

Having looked over the mpl_toolkits.basemap.__init__ module, I do see that the drawparallel method relies on a few globals; you can import those from the module into your own namespace:

from mpl_toolkits.basemap import Basemap, _cylproj, _pseudocyl

This is no different from other imports you'd make; the original drawparallel method also relies on import numpy as np and from matplotlib.lines import Line2D, which make both np and Line2D globals in the original module.

like image 140
Martijn Pieters Avatar answered Oct 30 '25 16:10

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!