我正在使用 Python,并且我有一個介面(一個只定義方法簽名的類),它由另外兩個類實作。現在我正在添加另一個實作介面/基類的包裝類,但實際上是在獲取其他類之一,而這個包裝類在大多數情況下只是呼叫兩個類之一。我想做一些 Python 魔法,以避免只定義我真正改變的方法。
下面是一個例子:
class SomeInterface(object):
def do_1(self):
raise Exception("please implement")
def do_2(self):
raise Exception("please implement")
def do_3(self):
raise Exception("please implement")
class Goo(SomeInterface):
def do_1(self):
print("I am goo 1")
def do_2(self):
print("I am goo 2")
def do_3(self):
print("I am goo 3")
class Foo(SomeInterface):
def do_1(self):
print("I am foo 1")
def do_2(self):
print("I am foo 2")
def do_3(self):
print("I am foo 3")
class WrappingInterface(SomeInterface):
def __init__(self, inf: SomeInterface):
self._inner = inf
def do_1(self):
self._inner.do_1()
def do_2(self):
self._inner.do_2()
def do_3(self):
self._inner.do_2()
print("And then doing something else")
基本上,我不想在包裝類中撰寫 do_1 和 do_2,而是想做一些魔術,并且只能撰寫相關代碼。
我嘗試使用 Mixin 來實作它,但它不起作用。也許裝飾者可以做到,但我不確定如何做到。
uj5u.com熱心網友回復:
我真的不明白你為什么要那樣做。您可以WrappingInterface從子類繼承您的(例如: from Foo):
代碼:
class WrappingInterface(Foo):
def do_3(self):
super().do_3()
print("And then doing something else")
test = WrappingInterface()
test.do_1()
test.do_2()
test.do_3()
輸出:
>>> python3 test.py
I am foo 1
I am foo 2
I am foo 3
And then doing something else
但是如果你真的需要擴展基類,那么你可以這樣做:
動態擴展基類:
class WrappingInterface(SomeInterface):
def __init__(self, inf: SomeInterface):
self._inner = inf
def do_3(self):
self._inner.do_3()
print("And then doing something else")
WrappingInterface = type("WrappingInterface", (Foo,), dict(WrappingInterface.__dict__))
test = WrappingInterface(Foo())
test.do_1()
test.do_2()
test.do_3()
輸出:
> python3 test.py
I am foo 1
I am foo 2
I am foo 3
And then doing something else
或者你可以在你的課堂上做任何事情(這有點麻煩,但它有效)。
代碼:
class WrappingInterface(SomeInterface):
def __init__(self, inf: SomeInterface):
self._inner = inf()
methods = [method for method in dir(inf) if not method.startswith('__')
and callable(getattr(inf, method))]
for method in methods:
if method in self.__class__.__dict__:
continue
setattr(WrappingInterface, method, getattr(inf, method))
def do_3(self):
self._inner.do_3()
print("And then doing something else")
test = WrappingInterface(Foo)
test.do_1()
test.do_2()
test.do_3()
輸出:
>>> python3 test.py
I am foo 1
I am foo 2
I am foo 3
And then doing something else
筆記:
我建議檢查Abstract Base Classes在 Python 中做一個“真正的”抽象。參考:https : //docs.python.org/3/library/abc.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/386957.html
上一篇:使用模板繼承鉆石時會出錯嗎?
