Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: writing a wrapper around a third-party class

I need some functionality from a class X of a third-party module m. I could just use m.X directly, but I may need to replace m.X with another class n.Y in the future (e.g., if I discover a better implementation).

I'd like to avoid changing the rest of the code in such a situation.

For now, I want the full interface of m.X, including initialization, to pass through unchanged. I wrote a wrapper W for m.X as follows:

class W(m.X):
    def __init__(self, *args):
        super().__init__(*args)

In the future, should the need arise, I plan to rewrite the above as:

class W(n.Y):
    def __init__(self, *args):
        super().__init__(*args)
    # override instance methods of n.Y that don't share the semantics with m.X
    # for example, in case f1 is hard to replicate in n.Y:
    # def f1(self, *args):
    #     print("this method is no longer available")
    #     raise MyDeprecatedMethod()
    # for example, in case f2 needs to be recalculated
    # def f2(self, *args):
          # do the calculations required to keep W.f2 unchanged 

Is my current wrapper for m.X acceptable? Are there are problems with it, or with the planned wrapper for n.Y?

like image 225
max Avatar asked Jan 27 '26 04:01

max


2 Answers

You could simply use

class W(m.X):
    pass

which inherits m.X.__init__() by default.

like image 155
erbridge Avatar answered Jan 29 '26 18:01

erbridge


The simplest method is to write:

W = m.X

Practically everything in Python is a first-class object - including types. A class is almost indistinguishable from any other variable, for example:

def W(*args, **kwargs):
    return m.X(*args, **kwargs)

can instantiate an instance of m.X while appearing that W is the actual name of it. (Note that with this method isinstance will not work correctly - it will work fine with the first example.)

In some cases, using assignment may not play nicely with IDEs. In this case:

class W(m.X): pass

will also produce the same result, though with the added overhead in that instances of W are only instances of m.X because W is a subclass: using W=m.X; W(args) will create an instance of m.X.

like image 45
Zooba Avatar answered Jan 29 '26 18:01

Zooba



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!