Reputation: 52273
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?
Upvotes: 3
Views: 2240
Reputation: 5392
This would depend on how different m.X and n.Y are in their methods you're using, but it could be as simple as
try:
import n.Y as foo
except ImportError:
import m.X as foo
class W(foo):
pass
so your code reflects the new module automatically, potentially minimizing the changes you need to make throughout your codebase.
Upvotes: 0
Reputation: 11438
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
.
Upvotes: 2
Reputation: 1386
You could simply use
class W(m.X):
pass
which inherits m.X.__init__()
by default.
Upvotes: 3