Python3类型注释和子类
我如何在Python类型注释中引用“任何子类化父类的对象” 示例:Python3类型注释和子类,python,python-3.x,types,Python,Python 3.x,Types,我如何在Python类型注释中引用“任何子类化父类的对象” 示例:FooBase是一个抽象基类,从中可以对Foo1、Foo2等进行子类化。我希望函数接受FooBase的任何后代。这样做是否可以: def do_something(self, bar:FooBase): pass 或者这只接受FooBase类的对象,当然这是不可能的,因为FooBase是抽象的?在这种情况下,我需要建立一个包含所有案例的联合体(上帝啊,我希望不是!),还是可以通过其他方式抽象地表达这种关系 这是否只接受类
FooBase
是一个抽象基类,从中可以对Foo1
、Foo2
等进行子类化。我希望函数接受FooBase
的任何后代。这样做是否可以:
def do_something(self, bar:FooBase):
pass
或者这只接受FooBase
类的对象,当然这是不可能的,因为FooBase
是抽象的?在这种情况下,我需要建立一个包含所有案例的联合体
(上帝啊,我希望不是!),还是可以通过其他方式抽象地表达这种关系
这是否只接受类为FooBase
的对象
不,这也将接受任何子类。这一点在类型暗示政治公众人物理论中也有阐述,具体如下:
如果t1
是t2
的子类型,则类型t1
与类型t2
一致。(但并非相反。)
在处理类型提示时,请查看它以获取更多的指针
我需要建立一个所有案例的联盟吗
即使您这样做了,所有子类都将从联合中删除,子类将被跳过。尝试创建您提到的联合体
:
typing.Union[Foo1, Foo2, FooBar]
结果应该是FooBar
。事实上,它是一个抽象类在这里并没有什么区别,Python本身在输入模块中使用了许多抽象类
例如size
abc;暗示具有大小的函数
允许替换任何虚拟子类(定义的类)
:
def foo(obj: Sized): pass
foo([1, 2, 3, 4]) # ok
foo([2, 3, 4, 5]) # ok
继承也适用于带注释的类型。属于FooBase
子类型的Foo
的任何实例也是FooBase
类型的有效对象。因此,您可以将FooBase
对象以及Foo
对象传递给函数
如果您想将函数仅限于FooBar
的子类,可以查看Type[C]
构造:。使用TypeVar
解决,PyCharm checker接受它:
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())