Python:如何使抽象类属性带有所有大写字母命名约定和linter警告

问题描述 投票:0回答:1

我有一个抽象的基类,具有恒定的类属性。

如何强制子类覆盖它?

我想保留all caps PEP8 convention为常数。


样本代码

from abc import ABC


class BaseClass(ABC):
    """Some abstract base class."""

    # How do I force children to override this?
    CONST_CLASS_ATTR = "base"


class ChildClass(BaseClass):
    """Child class."""

    CONST_CLASS_ATTR = "child"


潜在解决方案

这里已经有一个非常相似的问题:Abstract attributes in Python

但是,所有答案似乎都是解决方法。我想知道,有没有更简单的方法?

答案:https://stackoverflow.com/a/58321197/11163122

指示使用两个修饰符:abstractmethod + property

  • 优点:如果子类未实现CONST_CLASS_ATTR,并且由于子类抽象而无法实例化,则Linter会通知我
  • 缺点:Linter(pylint)现在抱怨invalid-name,我想让常量具有所有大写字母命名约定
from abc import ABC, abstractmethod


class AnotherBaseClass(ABC):
    """Some abstract base class."""

    @abstractmethod
    @property
    def CONST_CLASS_ATTR(self) -> str:
        return "base"


class AnotherChildClass(AnotherBaseClass):
    """Child class."""

    @property
    def CONST_CLASS_ATTR(self) -> str:
        return "child"

答案:https://stackoverflow.com/a/55544173/11163122

指示使用dunder方法__init_subclass__。更好,因为我的棉绒不再抱怨了,但是不太明显。

  • 优点:Linter不再抱怨invalid-name,并且由于提高了NotImplementedError而无法在运行时实例化>
  • 缺点:如果子类未实现CONST_CLASS_ATTR,Linter将不再发出警告。另外,这对我来说似乎很冗长]
from abc import ABC


class YetAnotherBaseClass(ABC):
    """Some abstract base class."""

    CONST_CLASS_ATTR: str

    @classmethod
    def __init_subclass__(cls):
        if not hasattr(cls, 'CONST_CLASS_ATTR'):
            raise NotImplementedError(
                f"Class {cls} lacks required CONST_CLASS_ATTR class attribute.")


class YetAnotherChildClass(YetAnotherBaseClass):
    """Child class."""

    CONST_CLASS_ATTR = "child"

我正在使用Python 3.6

我有一个抽象的基类,具有恒定的类属性。如何强制子类覆盖它?我想保留所有大写的PEP8约定作为常量。来自abc的示例代码...

python oop abstract abstract-methods class-attributes
1个回答
1
投票

我认为属性装饰器方法是最干净的。只是沉默pylint:

© www.soinside.com 2019 - 2024. All rights reserved.