“协议不能与isinstance()一起使用" - 为什么不? [英] "Protocols cannot be used with isinstance()" - why not?

查看:118
本文介绍了“协议不能与isinstance()一起使用" - 为什么不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的typing模块包含几个名称类似"SupportsInt"(-Float,-Bytes等)的对象.可能会阅读该模块的文档页面上的名称和说明,以建议您可以测试对象是否为支持__int__()"类型.但是,如果您尝试使用isinstance(),它会给出一个响应,使您清楚地知道这不是您要执行的操作:

The new typing module contains several objects with names like "SupportsInt" (-Float, -Bytes, etc.). The name, and the descriptions on the documentation page for the module, might be read to suggest that you can test whether an object is of a type that "supports __int__()". But if you try to use isinstance(), it gives a response that makes it clear that that isn't something you are meant to do:

>>> isinstance(5, typing.SupportsInt)
(Traceback omitted)
TypeError: Protocols cannot be used with isinstance().

另一方面,您可以使用issubclass():

On the other hand, you can use issubclass():

>>> issubclass((5).__class__, typing.SupportsInt)
True
>>> issubclass(type(5), typing.SupportsInt)
True

在这种情况下什么是协议"?为什么不允许以这种方式使用isinstance()?

What is a "protocol" in this context? Why does it disallow the use of isinstance() in this way?

推荐答案

这是PEP 484(typing模块的PEP)中给出的所有推理:

This is all of the reasoning given in PEP 484, the PEP for the typing module:

因为类型化.Callable双重职责代替了collections.abc.Callable,isinstance(x,类型.Callable)是通过推迟到`isinstance(x,collections.abc.Callable)来实现的.但是,不支持isinstance(x,键入.Callable [...]).

Because typing.Callable does double-duty as a replacement for collections.abc.Callable , isinstance(x, typing.Callable) is implemented by deferring to `isinstance(x, collections.abc.Callable) . However, isinstance(x, typing.Callable[...]) is not supported.

协议也称为magic method.这些是大多数python协议(完整列表此处):

A protocol is also known as a magic method. These are most of the python protocols (full list here):

>>> dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', 
'__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__']

我没有找到typing不支持isinstance的明确原因. issubclass起作用的原因是isinstance使用了typing不允许的__class_协议,而issubclass使用了允许的__subclasshook__协议.我相信原因是该功能已经在collections.abc.Callable中进行了编码,并且他们不想在typing模块中对其进行重新编码.

I have not found any clear reason for why typing does not support isinstance. The reason that issubclass works is that isinstance uses the __class_ protocol which is not allowed in typing, while issubclass uses the __subclasshook__ protocol which is allowed. I believe the reason is that the functionality was already coded in collections.abc.Callable and they did not want to recode it in the typing module.

这篇关于“协议不能与isinstance()一起使用" - 为什么不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆