[英]How can I specify a subtype of multiple types (including general types, like Callable) in Python type annotations?
One obvious example of this is multiple inheritance: if I have classes Foo
and Bar
, I can make a class Baz
that inherits from both ( class Baz(Foo, Bar): ...
).一个明显的例子是多个 inheritance:如果我有
Foo
和Bar
类,我可以制作一个继承自两者的 class Baz
( class Baz(Foo, Bar): ...
) However, I could also make another class with a different behavior, which still inherits from both Foo
and Bar
... or I could inherit from a third class, which makes a completely different type.但是,我也可以制作另一个具有不同行为的 class,它仍然继承自
Foo
和Bar
... Obviously, this is a niche use case, but is this supported in Python type annotations?显然,这是一个小众用例,但 Python 类型注释是否支持此功能? In the example case, I don't want to write
Baz
specifically - I only need to know the fact that a type is both Foo
and Bar
, but it can also be anything else.在示例情况下,我不想专门编写
Baz
- 我只需要知道类型既是Foo
又是Bar
的事实,但它也可以是其他任何东西。 I was thinking something along the lines of param: Foo | Bar
我在想一些类似于
param: Foo | Bar
param: Foo | Bar
or param: typing.Multiple[Foo, Bar]
. param: Foo | Bar
或param: typing.Multiple[Foo, Bar]
。
My specific use case: I want to use the Callable
syntax to specify parameter and return types (eg Callable[..., bool]
) but I also need to make sure that the argument is a FunctionType
, ie not a class or builtin_function_or_method.我的具体用例:我想使用
Callable
语法来指定参数和返回类型(例如Callable[..., bool]
),但我还需要确保参数是FunctionType
,即不是 class 或 builtin_function_or_method。 Of course, I could just specify this in the docstring - but is this supported in type annotations in a way that will work with type checkers?当然,我可以只在文档字符串中指定它——但是类型注释是否支持这种方式,可以与类型检查器一起使用?
There is a limited version of this through the Protocol class ( PEP , docs ) - however, it only supports type variables ( Protocol[T]
) and concrete types ( class MyProtocol(FunctionType, Protocol)
), but not general types like Any, Union, Callable, Iterator, etc. So, the example case in the question can be implemented as通过协议 class ( PEP , docs ) 有一个有限版本 - 但是,它只支持类型变量 (
Protocol[T]
) 和具体类型 ( class MyProtocol(FunctionType, Protocol)
),但不支持像 Any 这样的通用类型, Union、Callable、Iterator 等。因此,问题中的示例案例可以实现为
class FooAndBar(Foo, Bar, typing.Protocol): ...
but the use case mentioned below seems to be impossible ( might be possible eventually ), so for now I'd either define a Protocol with just the members you need, use a string as the type hint, or specify this in a docstring.但是下面提到的用例似乎是不可能的(可能最终可能),所以现在我要么定义一个只包含您需要的成员的协议,使用字符串作为类型提示,或者在文档字符串中指定它。
Additional note: if you use an IntelliJ IDE, you can write附加说明:如果您使用 IntelliJ IDE,您可以编写
assert isinstance(param, (Foo, Bar))
which will, for the purposes of type checking, achieve the same result as a hypothetical param: Intersection[Foo, Bar]
in any further code.出于类型检查的目的,这将在任何进一步的代码中实现与假设
param: Intersection[Foo, Bar]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.