python-3.x - 在 python3 中正确键入返回 self 的函数
问题描述
假设我有以下代码....
from __future__ import annotations
from typing import Any, TypeVar, Type
from typing_extensions import Literal
_T = TypeVar("_T")
class A:
@classmethod
def constructor(cls: Type[_T]) -> _T:
return cls()
def __enter__(self) -> A:
return self
def __exit__(self, *args: Any, **kwargs: Any) -> Literal[False]:
return False
class B(A):
pass
def test() -> None:
a_instance: A = A.constructor()
b_instance: B = B.constructor() # Works because constructor return type is _T
with B() as b:
a_instance = b
b_instance = b # Error, Incompatible types in assignment
如果我对上面的代码运行 mypy,我会收到以下警告
» mypy test.py
test.py:30: error: Incompatible types in assignment (expression has type "A", variable has type "B")
Found 1 error in 1 file (checked 1 source file)
这是因为A.__enter__
,( A
) 的返回类型是由 继承的B
,所以 mypy 认为B.__enter__
也返回A
。我想避免重新实现该功能只是为了更正类型提示......
class B(A):
def __enter__(self) -> B:
return super().__enter__() # type: ignore
我已经解决了类方法构造函数中的类似问题,方法是使用 aTypeVar
模板化类型,cls
以便我以后可以使用它,但我不确定类似的技巧如何适用于非类方法。
这种情况也适用于任何其他返回的方法self
。
解决方案
相信我想通了...
您还需要使用 TypeVar_T
来指示self
. 然后你可以重新使用它_T
作为返回类型。
注意,如果你想使用类的任何属性(就像我在下面做的print
那样),你还需要TypeVar
使用参数将 绑定到一个类bound
。
_T = TypeVar("_T", bound="A")
class A:
def __init__(self) -> None:
self.a_attr = 1
@classmethod
def constructor(cls: Type[_T]) -> _T:
return cls()
def __enter__(self: _T) -> _T:
print(self.a_attr)
return self
推荐阅读
- java - 使用 ElasticsearchTemplate 和聚合器获取聚合值
- python - django admin 删除登录页面
- css - CSS - 纵横比和 100% 视口高度
- java - 如何在Java中删除关系
- javascript - 使用 NodeJS 的 Web 服务,使用 javascript 从 html 页面模拟浏览器执行
- vba - MoveNext 方法上的 ADO 记录集数据类型不匹配
- google-cloud-billing - 是否可以获得每个项目的明确成本汇总?
- ios - 如何防止从 Swift 中的 UIImagePickerController 自动保存图像?
- c# - Entity Framework Core 是否支持复合类型?
- javascript - 找不到用 Google App Script 替换列中单元格中部分文本的方法