![](/img/trans.png)
[英]Python property and method override issue: why subclass property still calls the base class's method
[英]Determine if subclass has a base class's method implemented in Python
我有一個擴展基數 class 的 class。實例化后,我想檢查子類是否具有從其基類實現的類之一,但我不確定最佳方法。 hasattr(self, '[method]')
如果孩子沒有實現,則從 super 返回方法,所以我試圖區分它們。
這是一個例子:
class Base :
def __init__ ( self,) :
pass
def fail (self,) :
pass
# Now create the subclass w/o .fail
class Task ( Base ) :
def __init__ ( self, ):
print( hasattr( self, 'fail' ) ) # < returns True
當Task()
被實例化時,它打印True
因為Task
從Base
繼承.fail
。 但在這種情況下,我想知道Task
沒有實現.fail
,所以我想以某種方式返回False
。 好像我在尋找類似isimplemented( self, 'fail' )
的東西。 我錯過了什么?
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
Output:
t1 = Task()
# True
t2 = Task2()
# False
我不確定我是否理解正確,但聽起來您可能正在尋找抽象基類。 (此處為文檔,此處為教程。)如果您在繼承自abc.ABC
的基類 class 中指定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
# `fail` method has not been overridden in the subclass.
t1 = Task()
# this succeeds
# `fail` method has been overridden in the subclass.
t2 = Task2()
如果您希望檢查發生在class 定義時間而不是實例實例化時間,另一種選擇是在您的基類 class 中編寫一個__init_subclass__
方法,每次您對基類 class 進行子類化或從基類 class 繼承基類 class 時都會調用該方法.(你不必在__init_subclass__
中引發異常——你可以只向 class 添加一個fail_overriden
boolean 屬性,或者做任何你喜歡的事情。)
class Base:
def fail(self):
pass
def __init_subclass__(cls, **kwargs):
if cls.fail == Base.fail:
raise TypeError(
'Subclasses of `Base` must override the `fail` method'
)
super().__init_subclass__(**kwargs)
# this class definition raises an exception
# because `fail` has not been overridden
class Task(Base):
pass
# this class definition works fine.
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"
不確定我是否理解正確但你可以檢查fail
方法是否在類的vars
中,但沒有繼承到主要的 class。
所以你可以嘗試:
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
t1 = Task()
t2 = Task2()
Output:
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
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.