“Protocols cannot be used with isinstance()” - why not?

前端 未结 2 1163
一整个雨季
一整个雨季 2021-02-05 13:02

The new typing module contains several objects with names like \"SupportsInt\" (-Float, -Bytes, etc.). The name, and the descriptions on the documentation page for

相关标签:
2条回答
  • 2021-02-05 13:53

    As the documentation says: At runtime, isinstance(x, T) will raise TypeError. In general, isinstance() and issubclass() should not be used with types. ( https://docs.python.org/3/library/typing.html?highlight=typing#typing.TypeVar )

    0 讨论(0)
  • 2021-02-05 13:58

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

    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.

    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__']
    

    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.

    0 讨论(0)
提交回复
热议问题