Для проверки существования атрибута они работают как шарм:
Код: Выделить всё
from typing import Protocol, Callable, runtime_checkable
from collections import namedtuple
class HasItems(Protocol):
items: Callable
assert isinstance(dict(), HasItems)
assert not isinstance(list(), HasItems)
В некоторых случаях мне действительно хотелось бы иметь такой уровень сравнения.
< pre class="lang-py Prettyprint-override">
Код: Выделить всё
# @runtime_checkable # doesn't make a difference in what I'm checking
class HasIntItems(Protocol):
items: int
obj = namedtuple('IntItems', 'items')(3)
obj_with_no_items = namedtuple('IntItems', 'not_items')(3)
assert isinstance(obj.items, int) # obj has items and is an int
assert isinstance(obj, HasIntItems) # so this is true, and it's expected
assert not isinstance(obj_with_no_items, HasIntItems) # also expected
obj_w_non_int_items = namedtuple('IntItems', 'items')('i am not an int')
assert not isinstance(obj_w_non_int_items.items, int) # items exists, but is not an int
assert isinstance(obj_w_non_int_items, HasIntItems) # expected this to fail: items is a
assert isinstance(dict(), HasIntItems) # expected this to fail:dict() considered to have items, but it's a callable, not an int!
Подробнее здесь: https://stackoverflow.com/questions/675 ... attributes