我有一個擴展了一個基類的類。在實體化時,我想檢查子類是否有從其基類中實作的一個類,但我不確定最好的方法。 hasattr(self, '[method]')如果子類沒有實作,則回傳超類的方法,所以我想區分開來。
這里有一個例子:
class Base 。
def __init__ ( self,) 。
pass pass
def fail ( self,) :
pass pass
# 現在創建一個沒有.fail的子類。
class Task ( Base ) :
def __init__ ( self, ) 。
print( hasattr( self, 'fail' ) ) # < returns True
當Task()被實體化時,它列印出True,因為Task從Base繼承.fail。 但是在這種情況下,我想知道Task Does Not 實作.fail,所以我想以某種方式回傳False。 似乎我正在尋找類似于isimplemented( self, 'fail')的東西。我錯過了什么?
uj5u.com熱心網友回復:
IIUC,你可以檢查super().fail == self.fail
class Base。
def __init__(self):
pass.
def fail(self)。
pass。
class Task(Base)。
def __init__(self)。
print(super().fail == self.fail)
class Task2(Base)。
def __init__(self)。
print(super().fail == self.fail)
def fail(self)。
# Override: 覆寫
pass: # override.
輸出:
t1 = Task()
# 真
t2 = Task2()
# False[/span
uj5u.com熱心網友回復:
不確定我的理解是否正確,但你可以檢查fail方法是否在類的vars中,但沒有繼承到主類。
所以你可以試試:
class Base。
def __init__(self):
print(self.__dir__())
def fail(self)。
pass。
class Task(Base)。
def __init__(self)。
print('fail' not in vars(task))
class Task2(Base)。
def __init__(self)。
print('fail' not in vars(task2))
def fail(self)。
# Override: 覆寫
pass[/span
t1 = 任務()
t2 = Task2()
輸出:
True
False
或者使用__dict__:
...
class Task(Base)。
def __init__(self)。
print('fail' not in Task.__dict__)
class Task2(Base)。
def __init__(self)。
print('fail' not in Task2.__dict__)
def fail(self)。
# Override: 覆寫
pass。
...
uj5u.com熱心網友回復:
我不確定我的理解是否正確,但聽起來你似乎可能在尋找抽象基類。(檔案這里,教程這里。) 如果你在一個繼承自abc.ABC的基類中指定了一個abstractmethod,那么試圖實體化一個子類將會失敗,除非該子類覆寫了這個abstractmethod。
from abc import ABC, abstractmethod
class Base(ABC)。
@abstractmethod。
def fail(self)。
pass。
class Task(Base)。
pass
class Task2(Base)。
def fail(self)。
pass。
# this raises an exception: pass.
# `fail`方法在子類中沒有被重寫。
t1 = 任務()
# this succeeds
# `fail`方法在子類中被重寫了。
t2 = Task2()
如果你想在類定義時而不是實體實體化時進行檢查,另一個選擇是在你的基類中寫一個__init_subclass__方法,每次你子類你的基類或你子類繼承你的基類時都會呼叫這個方法。(你不必在__init_subclass__中引發一個例外--你可以在類中添加一個fail_overriden的布爾屬性,或者做任何你想做的事情。)
<
class Base:
def fail(self)。
pass。
def __init_subclass__(cls, **kwargs) 。
if cls.fail == Base.fail。
raise TypeError(
'Base的子類必須覆寫`fail'方法'。
)
super().__init_subclass__(**kwargs)
# 這個類定義引發了一個例外。
# 因為`fail`沒有被重寫。
class Task(Base)。
pass。
# 這個類的定義作業正常。
class Task2(Base)。
def fail(self)。
pass。
如果你只是想讓每個實體告訴你fail是否在其子類中被多載,你可以這樣做:
class Base。
def __init__(self):
print(type(self).fail != Base.fail)
def fail(self)。
pass。
class Task(Base)。
def __init__(self)。
super().__init__()
class Task2(Base)。
def __init__(self)。
super().__init__()
def fail(self)。
pass。
t1 = Task() # prints "True"
t2 = Task2() # prints "False"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/320062.html
標籤:
下一篇:只有一個基礎虛擬的多路徑繼承
