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



我有一个抽象基类,具有常量class属性。

如何强制子类覆盖它?

我想保留常数的所有caps PEP8约定。


样本代码

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"

潜在解决方案

这里已经有一个非常相似的问题: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

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

@abstractmethod
@property
def CONST_CLASS_ATTR(self) -> str:  # pylint: disable=invalid-name
return "base"

这只会使此特定方法及其覆盖的警告静音。

相关内容

  • 没有找到相关文章

最新更新