Как создать свойство уровня класса в абстрактном базовом классе (Python 3+), которое я хочу определить для производных классов? - PullRequest
0 голосов
/ 20 апреля 2019

Существует ли стандартный способ создания переменных уровня класса в абстрактном базовом классе (ABC), который мы хотим определить производными классами?

Я мог бы реализовать это с помощью следующих свойств:

from abc import ABC
from abc import abstractmethod

class Parent(ABC):
    @property
    @abstractmethod
    def provider(self) -> str:
        """The provider that the payload generator is applicable for"""
        raise NotImplementedError()

class Child(Parent):
    @property
    def provider(self) -> str:
        return 'some provider'

Но свойства связаны с экземплярами, а не с классами.Есть ли способ реализовать аналогичную функциональность для переменной класса в Python 3.6 +?

1 Ответ

0 голосов
/ 20 апреля 2019

Использовать пользовательский метакласс:

class RequireProperty(type):

    _required = ['define_me']

    def __new__(cls, name, bases, attributes):

        new_class = super().__new__(cls, name, bases, attributes)
        if not all(required_attribute in attributes for required_attribute in cls._required):
            raise TypeError

        else:
            return new_class

Если вы не определите атрибут:

class DidntDefine(metaclass=RequireProperty):
    pass

DidntDefine()

Выход:

TypeError: You must define all of ['define_me'].

Если вы делаете:

class DidDefine(metaclass=RequireProperty):

    define_me = None

DidDefine()

Выход:

<__main__.DidDefine at 0x2bcec632198>
...