为什么python中的显式协议不需要@runtimechecks的属性实现,而隐式协议需要?

2024-05-16 13:14:47 发布

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

如果协议是使用必需的属性实现的,即name

@runtime_checkable
class DuckProtocol(Protocol):
    """Protocol for a duck"""
    name: str
    @abstractmethod
    def quack(self):
        raise NotImplementedError

如果没有name属性,则隐式子类型上的isinstance运行时检查将失败,但显式子类型将不会:

class Duck1(DuckProtocol):
    def quack(self):
        print('quack')
        
class Duck2:
    def quack(self):
        print('quack')

class Duck3:
    def __init__(self):
        self.name = 'duck3'
    def quack(self):
        print('quack')

print(isinstance(Duck1(), DuckProtocol))
print(isinstance(Duck2(), DuckProtocol))
print(isinstance(Duck3(), DuckProtocol))

输出:

True
False
True

为什么此属性检查不扩展到显式子类型


Tags: nameself类型属性defprotocolclassisinstance
1条回答
网友
1楼 · 发布于 2024-05-16 13:14:47

Duck1()不遵循DuckProtocol协议定义的规范,但它仍然是协议类的实例,通常意义上的对象是类的实例:它的类型是Duck1,它是DuckProtocol类的子类。根据isinstance的默认规则,这使得Duck1()成为DuckProtocol的实例

运行时可检查协议定义了它们自己的isinstance逻辑(通过实现^{}),但是如果该逻辑不能确定对象是协议的实例,它将以delegating to ^{}结束,而不是返回False。经过一系列间接和委托之后,我们最终进入_abc._abc_subclasscheck,这checks for concrete subclasses是其处理的第4步,该检查返回True

相关问题 更多 >