Каков правильный способ аннотировать аргумент функции, который ожидает объект класса вместо экземпляра этого класса?Как аннотировать экземпляры типов (вместо экземпляров класса)?
В приведенном ниже примере, some_class
аргумент, как ожидается, будет экземпляр типа (которым является классом), но проблема в том, что type
слишком широк:
def construct(some_class: type, related_data:Dict[str, Any]) -> Any:
...
В случае, когда some_class
ожидает определенный набор типов объектов, используя type
, совсем не помогает. Модуль typing
может быть нуждается в классе общего, что делает это:
def construct(some_class: Class[Union[Foo, Bar, Baz]], related_data:Dict[str, Any]) -> Union[Foo, Bar, Baz]:
...
В приведенном выше примере, some_class
является Foo
, Bar
или Faz
класс, не экземпляр этого. Не должно иметь значения их позиции в дереве классов, потому что some_class: Class[Foo]
также должен быть действительным. Поэтому
# classes are callable, so it is OK
inst = some_class(**related_data)
или
# instances does not have __name__
clsname = some_class.__name__
или
# an operation that only Foo, Bar and Baz can perform.
some_class.a_common_classmethod()
должно быть ОК mypy, pytype, PyCharm и т.д.
Как это может быть сделано с текущей реализации (Python 3.6 или ранее)?
Если вам нужно быть более конкретным, чем 'type', введите метакласс или абстрактный базовый класс. – jonrsharpe
@jonrsharpe - Я думаю, что метакласс будет делать трюк, но я еще не достиг такого уровня в Python. С введением переменных аннотаций в 3.6 (в том числе «ClassVar', чтобы отличать переменные экземпляра от переменных класса), мне интересно, почему я должен использовать' type' для аннотирования объектов класса, когда существует так много способов аннотировать экземпляры класса. Может быть, мне придется ждать будущего обновления или рецепта :). –
Кажется, мне придется полагаться на 'typing.Type' и делать что-то вроде' Foo = TypeVar ['Foo', bond = Bar] ', где' Bar' является ABC, затем, взяв пример выше: ' def construct (some_class: Type [Foo], ...) -> Foo'. Мне особенно не нравится использовать 'TypeVar', но, похоже, это единственный способ ... –