我有一个抽象基类,其中包含一个常量类属性。
如何强制子类覆盖它?
我想保持全部大写PEP8约定的常量。
示例代码
潜在解决方案:
这里已经有一个非常相似的问题:Python中的抽象属性 然而,所有答案似乎都是变通方法。我想知道,是否有更简单的方法?
回答:https://dev59.com/U3E85IYBdhLWcg3whD7k#58321197 指示使用两个装饰器:
缺点:Linter (
答案:https://dev59.com/U3E85IYBdhLWcg3whD7k#55544173的回答建议使用dunder方法
优点:Linter不再抱怨
缺点:如果子类未实现
我正在使用Python 3.6。
如何强制子类覆盖它?
我想保持全部大写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://dev59.com/U3E85IYBdhLWcg3whD7k#58321197 指示使用两个装饰器:
abstractmethod
+ property
优点:Linter会提示我子类没有实现CONST_CLASS_ATTR
,并且由于它是抽象的,无法在运行时实例化缺点: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://dev59.com/U3E85IYBdhLWcg3whD7k#55544173的回答建议使用dunder方法
__init_subclass__
。这样做更好,因为我的linter不再抱怨,但它不够明显。优点:Linter不再抱怨
invalid-name
,并且由于引发NotImplementedError
而无法在运行时实例化。缺点:如果子类未实现
CONST_CLASS_ATTR
,linters不再警告。此外,这对我来说似乎有些啰嗦。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。