[英]Python 3 type annotations and subclasses
如何在 Python 类型注释中引用“任何子类化父类的对象”?
示例: FooBase
是一个抽象基类,从它Foo1
、 Foo2
等。 我希望该函数接受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 部分的总结:
如果
t1
是t2
的子类型,则类型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.