[英]Python 3 type annotations and subclasses
How do I refer to 'any object that subclasses a parent class' in Python type annotations?如何在 Python 类型注释中引用“任何子类化父类的对象”?
Example: FooBase
is an abstract base class, from which Foo1
, Foo2
, etc. are subclassed.示例: FooBase
是一个抽象基类,从它Foo1
、 Foo2
等。 I want the function to accept any descendant of FooBase
.我希望该函数接受FooBase
任何后代。 Will this do:这会不会:
def do_something(self, bar:FooBase):
pass
Or will this only accept an object of class FooBase
, which of course is impossible given that FooBase
is abstract?或者这只会接受FooBase
类的对象,鉴于FooBase
是抽象的,这当然是不可能的? In that case, do I need to build a Union
of all cases (please God I hope not!), or can I through some other way express this relationship abstractly?在这种情况下,我是否需要建立一个所有案例的Union
(拜托上帝,我希望不是!),或者我可以通过其他方式抽象地表达这种关系吗?
Inheritance also applies to annotated types.继承也适用于带注释的类型。 Any instance of Foo
which is a subtype of FooBase
is also a valid object of the type FooBase
.的任何实例Foo
其的子类型FooBase
也是类型的有效对象FooBase
。 So you can pass a FooBase
object but also a Foo
object to the function.因此,您可以将FooBase
对象和Foo
对象传递给函数。
If you want to limit the function to only subclasses of FooBar
, you could take a look at the Type[C]
construct: The type of class objects .如果您想将该功能限制为仅FooBar
子类,您可以查看Type[C]
构造: 类对象的类型。
will this only accept an object of class
FooBase
?这将只接受FooBase
类的对象吗?
No, this will accept any subclasses too.不,这也将接受任何子类。 This is also stated in the Theory of Type Hinting PEP, specifically the summary of Gradual Typing section :这也在 Theory of Type Hinting PEP 中有所说明,特别是 Gradual Typing 部分的总结:
A type
t1
is consistent with a typet2
ift1
is a subtype oft2
.如果t1
是t2
的子类型,则类型t1
与类型t2
一致。 (But not the other way around.) (但反过来不行。)
take a look at it for further pointers when dealing with type hints.在处理类型提示时,请查看它以获取更多指针。
do I need to build a Union of all cases.我是否需要建立一个所有案例的联盟。
Even if you did, all subclasses will be eliminated from the Union
and the subclasses are going to get skipped.即使你这样做了,所有的子类都将从Union
删除,子类将被跳过。 Try creating the Union
you mention:尝试创建您提到的Union
:
typing.Union[Foo1, Foo2, FooBar]
and the result should be FooBar
.结果应该是FooBar
。 The fact that it is an abstract class pays no difference here, Python itself uses many abstract classes in the typing
module.它是一个抽象类的事实在这里没有区别,Python 本身在typing
模块中使用了许多抽象类。
Take for example the Sized
abc;以Sized
abc 为例; hinting a function with Sized
allows any virtual subclass (classes defining __len__
) to be substituted:使用Sized
提示函数允许替换任何虚拟子类(定义__len__
类):
def foo(obj: Sized): pass
foo([1, 2, 3, 4]) # ok
foo([2, 3, 4, 5]) # ok
Solved using TypeVar
and PyCharm checker accepts it:使用TypeVar
解决,PyCharm 检查器接受它:
from pydantic import BaseModel
class MyModel(BaseModel):
pass
from typing import TypeVar
BaseModelType = TypeVar('BaseModelType', bound='BaseModel')
async def do_smth(value: BaseModelType):
pass
# ...
await do_smth(MyModel())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.