考慮一個父類Foo和我的類myFoo。我希望它isinstance(myFoo, Foo)回傳 True,但不從Foo.
例如
class Foo:
def __init__(self):
# do stuff
# tons of methods!
class myFoo:
def __init__(self):
# do stuff
# couple of methods not in common with Foo
這可能是一個小眾用例,但對我來說非常方便。我怎么能“愚弄”isinstance相信這myFoo是一個Foo實體而不做class myFoo(Foo),從而繼承大量的方法Foo。
編輯背景關系:
所以在我的例子中,Foo繼承自 Mixin 類,每個類都定義了一堆相關的方法。這些 Mixin 中定義的幾個方法都是以提供的,self if isinstance(self, Foo) else self.foo或者Foo提供了一個帶有Fooset 作為.foo屬性的類。
現在,我想定義一個不同的myFoo類,它只繼承其中的一些 Mixin。但是它們在檢查時不起作用isinstance(self, Foo)。更改 Mixin 或Foo類不是一個選項,因此我必須復制整個 Mixin 以及它可能呼叫的所有函式并對其進行編輯;或者我找到一種方法來“愚弄” Mixin,相信我提供給它的確實是一個Foo實體。
或者,我可以繼承Foo并覆寫/引發AttributeError對所有我不想作為myFoo.
uj5u.com熱心網友回復:
Python 實作了“虛擬子類化”的概念——它精確地允許一個類被宣告為另一個類的子類,而不必從那個類繼承。(也就是說,正是你的問題)。
唯一的要求是允許虛擬子類化的基類是用 abc.ABCMeta 元類創建的——即使你沒有使用抽象方法。它可以使用__subclasscheck__自定義元類中的較低級別來完成,但是 abc.ABC 已經準備好作業,包括.register呼叫,這也是需要的。
In [295]: import abc
In [296]: class Foo(abc.ABC):
...: def __init__(self):
...: # do stuff
...: ...
...: # tons of methods!
...:
...: class myFoo:
...: def __init__(self):
...: # do stuff
...: ...
...:
In [297]: Foo.register(myFoo)
Out[297]: __main__.myFoo
In [298]: issubclass(myFoo,Foo)
Out[298]: True
In [299]: isinstance(myFoo(), Foo)
Out[299]: True
如上例所示,abc.ABC 類具有允許虛擬子類化的機制,方法是添加一個僅限類的“注冊”方法。在此示例中無論如何myFoo都不要繼承自。Foo
至于
或者,我可以從 Foo 繼承并在呼叫我不希望作為 myFoo 一部分的所有方法時覆寫/引發 AttributeError。
這是可能的,但不太實用 - 可以通過仔細覆寫__getattribute__類并處理應隱藏在繼承類中的方法串列來完成。
uj5u.com熱心網友回復:
聽起來像是對https://en.wikipedia.org/wiki/Liskov_substitution_principle的嚴重違反。也許您可以提取一個具有您想要的介面的超類,然后讓兩個類都從它繼承。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/446642.html
標籤:Python python-3.x 目的 哎呀 遗产
