【发布时间】:2019-08-24 04:01:58
【问题描述】:
我想要一个抽象类,它强制每个派生类在其__init__ 方法中设置某些属性。
我查看了几个没有完全解决我的问题的问题,特别是here 或here。 This 看起来很有希望,但我无法让它发挥作用。
我假设我想要的结果可能类似于以下伪代码:
from abc import ABCMeta, abstractmethod
class Quadrature(object, metaclass=ABCMeta):
@someMagicKeyword #<==== This is what I want, but can't get working
xyz
@someMagicKeyword #<==== This is what I want, but can't get working
weights
@abstractmethod
def __init__(self, order):
pass
def someStupidFunctionDefinedHere(self, n):
return self.xyz+self.weights+n
class QuadratureWhichWorks(Quadrature):
# This shall work because we initialize xyz and weights in __init__
def __init__(self,order):
self.xyz = 123
self.weights = 456
class QuadratureWhichShallNotWork(Quadrature):
# Does not initialize self.weights
def __init__(self,order):
self.xyz = 123
以下是我尝试过的一些事情:
from abc import ABCMeta, abstractmethod
class Quadrature(object, metaclass=ABCMeta):
@property
@abstractmethod
def xyz(self):
pass
@property
@abstractmethod
def weights(self):
pass
@abstractmethod
def __init__(self, order):
pass
def someStupidFunctionDefinedHere(self, n):
return self.xyz+self.weights+n
class QuadratureWhichWorks(Quadrature):
# This shall work because we initialize xyz and weights in __init__
def __init__(self,order):
self.xyz = 123
self.weights = 456
然后我尝试创建一个实例:
>>> from example1 import *
>>> Q = QuadratureWhichWorks(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class QuadratureWhichWorks with abstract methods weights, xyz
>>>
哪个告诉我要实现这些方法,但我以为我说的是properties?
我目前的解决方法有一个缺陷,即__init__ 方法可以在派生类中被覆盖,但现在这至少确保(对我而言)我始终知道请求的属性已设置:
from abc import ABCMeta, abstractmethod
class Quadrature(object, metaclass=ABCMeta):
@abstractmethod
def computexyz(self,order):
pass
@abstractmethod
def computeweights(self,order):
pass
def __init__(self, order):
self.xyz = self.computexyz(order)
self.weights = self.computeweights(order)
def someStupidFunctionDefinedHere(self, n):
return self.xyz+self.weights+n
class QuadratureWhichWorks(Quadrature):
def computexyz(self,order):
return order*123
def computeweights(self,order):
return order*456
class HereComesTheProblem(Quadrature):
def __init__(self,order):
self.xyz = 123
# but nothing is done with weights
def computexyz(self,order):
return order*123
def computeweights(self,order): # will not be used
return order*456
但问题是
>>> from example2 import *
>>> Q = HereComesTheProblem(10)
>>> Q.xyz
123
>>> Q.weights
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'HereComesTheProblem' object has no attribute 'weights'
这是如何正确实现的?
【问题讨论】:
-
一种选择是让子类调用超类的
__init__函数。请参阅此问题以了解如何做到这一点stackoverflow.com/questions/2399307/… -
在
HereComesTheProblem的情况下,您是否希望weightsattr 初始化为None,或者您是否希望在创建HereComesTheProblem的实例时,应该抛出错误“未提供重量”? -
@pnv 我在尝试创建
HereComesTheProblem的实例时需要一条错误消息。 -
@k1next 你能看看我在下面给出的解决方案并给出一些反馈
标签: python oop abstract-class