Python ABC 类: 必须覆盖多个方法之一
Python ABC classes: One of multiple methods has to be overridden
在Python中,我有一个抽象基class,它有四个方法,其中至少有一个必须被覆盖。是否可以用 @abstractmethod
装饰器或类似的东西以某种方式实现它?
这是基础的精简版 class:
from abc import ABCMeta
class Base(metaclass=ABCMeta):
def __init__(self, var):
self.var = var
def a(self, r):
return self.var - self.b(r)
def b(self, r):
return self.var * self.c(r)
def c(self, r):
return 1. - self.d(r)
def d(self, r):
return self.a(r) / self.var
这四种方法具有某种循环依赖性,subclass 必须至少覆盖其中一种方法。其余的方法然后从基础 class.
开始工作
这可能看起来有点奇怪,但在我正在处理的应用程序中它非常有意义。
感谢@NChauhan 的提示,我想出了以下解决方案,感谢@NChauhan 和@greeeeeeeen 的第二个提示,解决方案变得更短且更易读:
from abc import ABCMeta
class Base(metaclass=ABCMeta):
def __init__(self, var):
self.var = var
def __init_subclass__(cls):
super().__init_subclass__()
def a(self, r):
return self.var - self.b(r)
def b(self, r):
return self.var * self.c(r)
def c(self, r):
return 1. - self.d(r)
def d(self, r):
return self.a(r) / self.var
if not hasattr(cls, 'a'):
cls.a = a
if not hasattr(cls, 'b'):
cls.b = b
if not hasattr(cls, 'c'):
cls.c = c
if not hasattr(cls, 'd'):
cls.d = d
if not any(hasattr(cls, method) for method in ('a', 'b', 'c', 'd')):
raise TypeError(f"Can't instantiate class '{cls.__name__}', " +
"without overriding at least on of the methods " +
"'a', 'b', 'c', or 'd'.")
如果我不分配 __init_subclass__
方法中的四个方法,hasattr
会 return True
,因为这些方法会被继承。
在Python中,我有一个抽象基class,它有四个方法,其中至少有一个必须被覆盖。是否可以用 @abstractmethod
装饰器或类似的东西以某种方式实现它?
这是基础的精简版 class:
from abc import ABCMeta
class Base(metaclass=ABCMeta):
def __init__(self, var):
self.var = var
def a(self, r):
return self.var - self.b(r)
def b(self, r):
return self.var * self.c(r)
def c(self, r):
return 1. - self.d(r)
def d(self, r):
return self.a(r) / self.var
这四种方法具有某种循环依赖性,subclass 必须至少覆盖其中一种方法。其余的方法然后从基础 class.
开始工作这可能看起来有点奇怪,但在我正在处理的应用程序中它非常有意义。
感谢@NChauhan 的提示,我想出了以下解决方案,感谢@NChauhan 和@greeeeeeeen 的第二个提示,解决方案变得更短且更易读:
from abc import ABCMeta
class Base(metaclass=ABCMeta):
def __init__(self, var):
self.var = var
def __init_subclass__(cls):
super().__init_subclass__()
def a(self, r):
return self.var - self.b(r)
def b(self, r):
return self.var * self.c(r)
def c(self, r):
return 1. - self.d(r)
def d(self, r):
return self.a(r) / self.var
if not hasattr(cls, 'a'):
cls.a = a
if not hasattr(cls, 'b'):
cls.b = b
if not hasattr(cls, 'c'):
cls.c = c
if not hasattr(cls, 'd'):
cls.d = d
if not any(hasattr(cls, method) for method in ('a', 'b', 'c', 'd')):
raise TypeError(f"Can't instantiate class '{cls.__name__}', " +
"without overriding at least on of the methods " +
"'a', 'b', 'c', or 'd'.")
如果我不分配 __init_subclass__
方法中的四个方法,hasattr
会 return True
,因为这些方法会被继承。