确定 subclass 是否在 Python 中实现了基础 class 的方法
Determine if subclass has a base class's method implemented in Python
我有一个扩展基数 class 的 class。实例化后,我想检查 subclass 是否具有从其基础实现的 classes 之一,但我不确定最好的方法。 hasattr(self, '[method]')
returns 来自 super 的方法如果没有被 child 实现,所以我试图区分它们。
这是一个例子:
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
输出:
t1 = Task()
# True
t2 = Task2()
# False
不确定我是否理解正确,但您可以检查 fail
方法是否在 class 的 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()
输出:
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
...
我不确定我是否理解正确,但听起来您可能正在寻找抽象基础类。 (文档 here, tutorial here。)如果您在继承自 abc.ABC
的基 class 中指定 abstractmethod
,则尝试实例化子 class 将失败,除非subclass 覆盖抽象方法。
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 中写一个 方法,每次你 subclass 你的基础 class 或你 subclass a class 时都会调用它继承自您的基地 class。 (你不必在 __init_subclass__
中引发异常——你可以只向 class 添加一个 fail_overriden
布尔属性,或者做任何你喜欢的事情。)
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 中被覆盖,您可以这样做:
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"
我有一个扩展基数 class 的 class。实例化后,我想检查 subclass 是否具有从其基础实现的 classes 之一,但我不确定最好的方法。 hasattr(self, '[method]')
returns 来自 super 的方法如果没有被 child 实现,所以我试图区分它们。
这是一个例子:
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
输出:
t1 = Task()
# True
t2 = Task2()
# False
不确定我是否理解正确,但您可以检查 fail
方法是否在 class 的 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()
输出:
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
...
我不确定我是否理解正确,但听起来您可能正在寻找抽象基础类。 (文档 here, tutorial here。)如果您在继承自 abc.ABC
的基 class 中指定 abstractmethod
,则尝试实例化子 class 将失败,除非subclass 覆盖抽象方法。
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 添加一个 fail_overriden
布尔属性,或者做任何你喜欢的事情。)
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 中被覆盖,您可以这样做:
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"