繁体   English   中英

Python 3 类型注解和子类

[英]Python 3 type annotations and subclasses

如何在 Python 类型注释中引用“任何子类化父类的对象”?

示例: FooBase是一个抽象基类,从它Foo1Foo2等。 我希望该函数接受FooBase任何后代。 这会不会:

def do_something(self, bar:FooBase):
    pass

或者这只会接受FooBase类的对象,鉴于FooBase是抽象的,这当然是不可能的? 在这种情况下,我是否需要建立一个所有案例的Union (拜托上帝,我希望不是!),或者我可以通过其他方式抽象地表达这种关系吗?

继承也适用于带注释的类型。 的任何实例Foo其的子类型FooBase也是类型的有效对象FooBase 因此,您可以将FooBase对象和Foo对象传递给函数。

如果您想将该功能限制为仅FooBar子类,您可以查看Type[C]构造: 类对象的类型

这将只接受FooBase类的对象吗?

不,这也将接受任何子类。 这也在 Theory of Type Hinting PEP 中有所说明,特别是 Gradual Typing 部分总结

如果t1t2的子类型,则类型t1与类型t2一致。 (但反过来不行。)

在处理类型提示时,请查看它以获取更多指针。

我是否需要建立一个所有案例的联盟。

即使你这样做了,所有的子类都将从Union删除,子类将被跳过。 尝试创建您提到的Union

typing.Union[Foo1, Foo2, FooBar]

结果应该是FooBar 它是一个抽象类的事实在这里没有区别,Python 本身在typing模块中使用了许多抽象类。

Sized abc 为例; 使用Sized提示函数允许替换任何虚拟子类(定义__len__类):

def foo(obj: Sized): pass

foo([1, 2, 3, 4]) # ok
foo([2, 3, 4, 5]) # ok

使用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.

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