我需要来自第三方模块m的X类的一些功能。我可以直接使用m.X,但是我可能需要在将来用另一个类n.Y替换m.X(例如,如果我发现更好的实现)。
在这种情况下,我想避免更改其余的代码。
现在,我希望m.X的完整界面(包括初始化)不变地传递。我为m.X写了一个包装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
我当前的m.X包装是否可以接受?是否存在问题,或者是否存在n.Y的计划包装?
答案 0 :(得分:3)
你可以简单地使用
class W(m.X):
pass
默认继承m.X.__init__()
。
答案 1 :(得分:2)
最简单的方法是写:
W = m.X
实际上Python中的所有东西都是一流的对象 - 包括类型。一个类几乎与任何其他变量无法区分,例如:
def W(*args, **kwargs):
return m.X(*args, **kwargs)
可以实例化m.X的实例,同时显示W是它的实际名称。 (请注意,使用此方法isinstance
将无法正常工作 - 将与第一个示例一起使用。)
在某些情况下,使用赋值可能无法很好地与IDE配合使用。在这种情况下:
class W(m.X): pass
也会产生相同的结果,但W
的实例仅增加了m.X
的实例,因为W
是一个子类:使用W=m.X; W(args)
将创建m.X
。
答案 2 :(得分:0)
这取决于你使用的方法中m.X和n.Y的差异,但它可能就像
一样简单try:
import n.Y as foo
except ImportError:
import m.X as foo
class W(foo):
pass
因此,您的代码会自动反映新模块,可能会最大限度地减少您在整个代码库中所做的更改。