Leo*_*rdo 11 python oop inheritance abstract-class class
我想知道在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
Run Code Online (Sandbox Code Playgroud)
在示例中,抽象类MyBaseClass具有:
foo_prop将在子类中定义
的抽象属性get_something将在子类中实现的抽象类方法get,它依次使用上面提到的(尚未定义的)抽象方法和属性。问题:
有没有更好的方法来定义抽象属性?在MyBaseClassset 中定义一个具体属性为 None 并在子类中重新定义它是否更有意义?
我可以在抽象类中混合抽象方法和具体方法吗,如示例所示?
如果是,声明类是否总是有意义的,或者具体的类可以具有抽象方法(在这种情况下,无论如何都不应该直接实例化)。
谢谢
根据文档(括号中的文本和我的代码格式):
[
@abstractproperty是]已过时,因为版本3.3:现在有可能使用property,property.getter(),property.setter()和property.deleter()用abstractmethod(),使得这个装饰冗余。
所以我认为你做得对。
您可以这样做,或者至少根据我的经验,这不是问题。也许其他人可以提供其他建议,但该建议可能会采用“继承不好”的形式。尽管我在文档中没有明确看到任何关于它的内容,但本节显示了一个示例,其中抽象方法、具体方法和类方法都在 ABC 中定义。
我相信您仍然必须声明类抽象才能使用@abstractmethod和类似的装饰器。通过将元类设置为 ABC,在定义所有抽象方法之前无法实例化该类,这听起来像是您想要的行为,所以我认为您需要将其声明为抽象,除非您只想依靠文档来强制执行“您不得在此类上实例化”规则。顺便说一句,您可以使用以下命令声明您的抽象类:
from abc import ABC
class MyBaseClass(ABC):
# ...
Run Code Online (Sandbox Code Playgroud)
继承abc而不是手动设置元类。我认为这种结构是首选。