我想知道在python(3)中抽象类是否可以有具体的方法 虽然这似乎有效,但我不确定这是在python中执行此操作的正确方法:
from abc import ABCMeta, abstractclassmethod, abstractmethod
class MyBaseClass:
__metaclass__ = ABCMeta
@property
@abstractmethod
def foo_prop(self):
"""Define me"""
pass
@abstractclassmethod
def get_something(cls, param1, param2, param3):
"""This is a class method, override it with @classmethod """
pass
@classmethod
def get(cls, param1, param2):
"""Concrete method calling an abstract class method and an abstract property"""
if param1 < cls.foo_prop:
raise Exception()
param3 = param1 + 42
item = cls.get_something(param1, param2, param3)
return item
class MyConcreteClassA(MyBaseClass):
"""Implementation """
foo_prop = 99
@classmethod
def get_something(cls, param1, param2, param3):
return cls.foo_prop + param1 + param2 + param3
class MyConcreteClassB(MyBaseClass):
"""Implementation """
foo_prop = 255
@classmethod
def get_something(cls, param1, param2, param3):
return cls.foo_prop - param1 - param2 - param3
在示例中,抽象类MyBaseClass
具有:
foo_prop
get_something
get
,它依次使用上面提到的(尚未定义的)抽象方法和属性。问题:
有没有更好的方法来定义抽象属性?将MyBaseClass
中的具体属性设置为None并在子类中重新定义它会更有意义吗?
我可以在抽象类中混合抽象和具体方法,如示例所示吗?
如果是,那么声明类抽象或者具体类是否具有抽象方法总是有意义的(在这种情况下,它永远不应该直接实例化)。
由于
答案 0 :(得分:2)
根据the docs(括号中的文字和我的代码格式):
[
@abstractproperty
是]从版本3.3开始不推荐使用:现在可以将property
,property.getter()
,property.setter()
和property.deleter()
与{{1}一起使用,使这个装饰者多余。
所以我认为你做得对。
你可以这样做,或者至少根据我的经验,这不是问题。也许其他人可以提供其他建议,但这个建议可能采取的形式是&#34;继承是坏的&#34;。虽然我在文档中没有明确地看到任何内容,this section shows an example其中抽象方法,具体方法和类方法都在ABC中定义。
我相信您仍然必须声明类抽象才能使用abstractmethod()
和类似的装饰器。通过将元类设置为ABC,在定义所有抽象方法之前无法实例化类,这听起来像您想要的行为,所以我认为您需要将其声明为抽象,除非您只是想依靠文档来强制执行&# 34;你不应该实例化#34;关于这门课的规则。另外,you can declare your abstract class with:
@abstractmethod
继承自from abc import ABC
class MyBaseClass(ABC):
# ...
而不是手动设置元类。我认为这种结构是首选。