python:围绕第三方类编写包装器

发布于 2024-10-12 20:34:55 字数 843 浏览 1 评论 0原文

我需要第三方模块 m 的 X 类的一些功能。我可以直接使用 mX,但将来我可能需要用另一个类 nY 替换 mX(例如,如果我发现更好的实现)。

我想避免在这种情况下更改其余代码。

目前,我希望 mX 的完整接口(包括初始化)保持不变。我为 mX 编写了一个包装器 W,如下所示:

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

将来,如果有需要,我计划将上面的内容重写为:

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 

我当前的 mX 包装器可以接受吗?它或者纽约计划的包装有问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜司空 2024-10-19 20:34:56

这取决于您使用的方法中 mX 和 nY 的不同程度,但它可能很简单,以便

try:
    import n.Y as foo
except ImportError:
    import m.X as foo

class W(foo):
    pass

您的代码自动反映新模块,从而可能最大限度地减少您需要在整个代码库中进行的更改。

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.

鹿! 2024-10-19 20:34:55

您只需使用

class W(m.X):
    pass

默认继承 mX__init__() 即可。

You could simply use

class W(m.X):
    pass

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

定格我的天空 2024-10-19 20:34:55

最简单的方法是这样写:

W = m.X

实际上,Python 中的所有内容都是一流对象 - 包括类型。类与任何其他变量几乎没有区别,例如:

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

可以实例化 mX 的实例,同时看起来 W 是它的实际名称。 (请注意,使用此方法 isinstance 将无法正常工作 - 它与第一个示例一起正常工作。)

在某些情况下,使用赋值可能无法在 IDE 中很好地发挥作用。在这种情况下:

class W(m.X): pass

也会产生相同的结果,尽管 W 的实例只是 mX 的实例,因为 W 是子类:使用 W=mX; W(args) 将创建 mX 的实例。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文