强制子类覆盖父类的属性

Jai*_*bar 0 python oop

基于这个问题:Force child class to overrideparent'smethods,我的需要是在类中设置一个必须由子类覆盖的属性:

class Parent(ABC):
    property = None # this one must be defined

# this should fail
class Child(Parent):
    pass
Run Code Online (Sandbox Code Playgroud)

谢谢!

che*_*ner 7

您可以使用__init_subclass__(其目的是通过简单的继承提供类似元类的功能)。

class Parent:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        if not hasattr(cls, 'property'):
            raise TypeError("Subclass must define class attribute 'property'")

class ChildThatWorks(Parent):
    property = 3

class ChildThatFails(Parent):
    pass
Run Code Online (Sandbox Code Playgroud)

一个有趣的选项是作为关键字参数传递property,而不是在类语句主体中进行赋值。

class Parent:
    def __init_subclass__(cls, *, property, **kwargs):
        setattr(cls, 'property', property)

class ChildThatWorks(Parent, property=3):
    pass

class ChildThatFails(Parent):
    pass
Run Code Online (Sandbox Code Playgroud)

ChildThatFails将产生以下回溯:

Traceback (most recent call last):
  File "/Users/chepner/tmp.py", line 8, in <module>
    class ChildThatFails(Parent):
TypeError: __init_subclass__() missing 1 required keyword-only argument: 'property'
Run Code Online (Sandbox Code Playgroud)

代码更简单,但处理无法提供值的灵活性较差property