用类方法实现抽象类不会引发异常

2024-10-03 09:12:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一个方法实现为一个抽象方法和一个类方法,但这样做并没有获得抽象类的任何好处。你知道吗

例如:

from abc import ABC, abstractmethod

class BasePipeline(ABC):

    @classmethod
    @abstractmethod
    def consume_frame(cls):
        pass

    @abstractmethod
    def consume_frame_two(self):
        pass

class AnotherSubclass(BasePipeline):

    @classmethod
    def does_nothing(cls):
        a = 1 + 1

# Call it. 
AnotherSubclass.consume_frame()

这不会引发任何异常,也不会出错。我希望它能说一些类似于:consume_frame_two is not implementedconsume_frame is not implemented的话。你知道吗

不确定我的行为是什么,或者我只是做错了什么。如果AnotherSubclass.consume_frame()没有正确地实现为类方法,我希望它引发一个异常。你知道吗


Tags: 方法isdefnotpassframeclasscls
1条回答
网友
1楼 · 发布于 2024-10-03 09:12:20

您的代码没有尝试创建AnotherSubclass类的实例。它所做的只是访问标记为抽象的classmethod的实现。Python的ABC抽象类并不打算阻止这种访问。你知道吗

abc模块旨在帮助您定义一个协议接口,一个基类,它设置了对应该被视为相同的具体对象上必须存在哪些属性的期望。你知道吗

为此,使用ABC子类所能做的就是防止在类层次结构中创建至少具有一个abstractmethodabstractproperty属性的任何类的实例。从^{} documentation

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

任何abstractmethod修饰的方法仍然可以调用;没有任何机制可以阻止这种情况,而具体实现可以使用super().name()访问abstractmethod对象的实现实际上是模块的一个特定目标。来自同一来源:

The abstract methods can be called using any of the normal ‘super’ call mechanisms

以及

Note: Unlike Java abstract methods, these abstract methods may have an implementation. This implementation can be called via the super() mechanism from the class that overrides it. This could be useful as an end-point for a super-call in a framework that uses cooperative multiple-inheritance.

该类的任何其他属性的使用方式与其他类相同,包括classmethod对象。你知道吗

在封面下,每个ABCMeta元类为您创建的每个类提供了一个__abstractmethods__属性,它是一个frozenset对象,该对象的__isabstractmethod__属性设置为True的类上的任何属性的名称,子类只需使用与父抽象方法对象相同的名称,将其设置为__isabstractmethod__未设置为true的属性可从该类的集合中删除该名称。当您试图创建一个类的实例,而该类的__abstractmethods__不是空的时,Python将引发一个异常。你知道吗

如果您需要进一步锁定您的类定义,那么您必须提出我们自己的元类或其他机制来实现这些规则。例如,您可以将classobject属性包装到自己的descriptor object中,以防止调用绑定到具有非空__abstractmethods__属性的类的classmethod。你知道吗

相关问题 更多 >