开发者

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 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜