简体   繁体   English

如何在 Python 类型注解中指定多个类型的子类型(包括通用类型,如 Callable)?

[英]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:如果我有FooBar类,我可以制作一个继承自两者的 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,它仍然继承自FooBar ... 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 | Barparam: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM