Typing.Protocol и typing.runtime_checkablePython

Программы на Python
Ответить
Anonymous
 Typing.Protocol и typing.runtime_checkable

Сообщение Anonymous »

У меня есть следующий код
from typing import Protocol, runtime_checkable

@runtime_checkable
class A(Protocol):
def f(self): ...

class B:
def f(self): ...

if __name__ == '__main__':
assert isinstance(B(), A)

Если я удалю декоратор runtime_checkable, я получу следующее исключение:
TypeError: Instance and class checks can only be used with @runtime_checkable protocols

Однако, если я добавлю атрибут в класс A, декоратор не понадобится.
class A(Protocol):
x: int
def f(self): ...

результат:
>>> assert isinstance(B(), A)
Traceback (most recent call last):
File "", line 1, in
AssertionError

Протокол, который содержит хотя бы один член, не являющийся методом, называется протоколом данных (typing.python.org). Почему протоколам данных не нужен декоратор runtime_checkable? Я не могу найти ничего об этом в документации.
РЕДАКТИРОВАТЬ:
без атрибута:
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Protocol
>>> class A(Protocol):
... def f(self): ...
...
>>> class B:
... def f(self): ...
...
>>> assert isinstance(B(), A)
Traceback (most recent call last):
File "", line 1, in
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\typing.py", line 1146, in __instancecheck__
issubclass(instance.__class__, cls)):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\abc.py", line 123, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\typing.py", line 1208, in _proto_hook
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols

с атрибутом:
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Protocol
>>> class A(Protocol):
... x: int
... def f(self): ...
...
>>> class B:
... def f(self): ...
...
>>> assert isinstance(B(), A)
Traceback (most recent call last):
File "", line 1, in
AssertionError

В версии Python >= 3.10 я получаю ошибку TypeError:
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Protocol
>>> class A(Protocol):
... x: int
... def f(self): ...
...
>>> class B:
... def f(self): ...
...
>>> assert isinstance(B(), A)
Traceback (most recent call last):
File "", line 1, in
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\typing.py", line 1498, in __instancecheck__
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols

3.12
Python 3.12.10 (tags/v3.12.10:0cc8128, Apr 8 2025, 12:21:36) [MSC v.1943 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Protocol
>>> class A(Protocol):
... x: int
... def f(self): ...
...
>>> class B:
... def f(self): ...
...
>>> assert isinstance(B(), A)
Traceback (most recent call last):
File "", line 1, in
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\typing.py", line 1917, in __instancecheck__
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols


Подробнее здесь: https://stackoverflow.com/questions/799 ... -checkable
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»