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 a开发者_如何转开发s 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?
You could simply use
class W(m.X):
pass
which inherits m.X.__init__()
by default.
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
.
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.
精彩评论