python - 如何注释返回 self 的方法,以便存根文件显示正确的返回类型?
问题描述
借口:这段代码没用,用例也可能没用,但我只是想弄清楚如何使它工作,以便存根文件显示正确的签名。这个问题似乎令人困惑,所以我正在尽力解释,但我非常愿意接受使问题结构更好的建议。
环境:Python:3.7.9 Mypy Vscode + Pylance
目录结构:
.
├── 1.py
└── testcode
├── __init__.py
└── modules
├── __init__.py
└── something.py
里面1.py
from testcode import Entry
e = Entry('a').a_function().b_function().c_function()
里面__init__.py
from .modules.something import Something, AnotherThing
class Entry(Something, AnotherThing):
def __init__(self, a: str):
self.a = a
在这种情况下,return self
是 的实例Entry
。当我没有在b_function
(或 a、b、c 函数)中指定返回类型时,类型提示是正确的。
但是当我将返回类型指定为 时Entry
,返回类型显示为Any
something.py
带有注释的返回类型:
class Something(object):
def a_function(self) -> 'Entry':
return self
def b_function(self) -> 'Entry':
return self
class AnotherThing:
def c_function(self) -> 'Entry':
return self
因此,为了尝试克服这个问题,我尝试使用创建所有文件stubgen
的命令创建存根文件,其中包括:stubgen -o . -p testcode
pyi
something.pyi
class Something:
def a_function(self) -> Entry: ...
def b_function(self) -> Entry: ...
class AnotherThing:
def c_function(self) -> Entry: ...
存根生成后的目录:
.
├── 1.py
└── testcode
├── __init__.py
├── __init__.pyi
└── modules
├── __init__.py
├── __init__.pyi
├── something.py
└── something.pyi
现在我明白了为什么这不起作用,因为当我Entry
在方法中指定返回类型时Something
,python 不知道Entry
在下一个屏幕截图中可以看到什么。所以它将Any
类型分配给它:
问题:
知道当Entry
方法的返回类型未在 for 中注释时Something
,它会选择正确的返回类型(因此提供了很好的智能感知),我如何正确注释和生成存根文件,以便Any
当返回类型为 self 时它不会返回注释?
编辑:
反思第一个答案,绑定子类并不能完全解决问题,因为智能感知和类型将仅显示调用的方法方法。例如,如果我调用a_function
,c_function
将不会显示,反之亦然。当我没有在Something
andAnotherThing
类的返回类型上键入提示,并且 vscode 正确假设是返回类型时,我可以在调用时Entry
获得智能感知c_function
a_function
解决方案
解决方案是使self
您的参数Something
和AnotherThing
函数绑定到这些类的子类,TypeVar
如下所示:
from typing import TypeVar
ST = TypeVar('ST', bound='Something')
class Something:
def a_function(self: ST) -> ST:
return self
def b_function(self: ST) -> ST:
return self
AT = TypeVar('AT', bound='AnotherThing')
class AnotherThing:
def c_function(self: AT) -> AT:
return self
更多信息可以在这里找到。
推荐阅读
- reporting-services - 需要将 Microstrategy 报告转换为 SSRS 平台的最佳实践或工具
- mongodb - mongodb $facet 未接受的结果
- python - 如何在 Pandas 中去除字符串列开头和结尾的标点符号
- mysql - Ejabberd Disco Itam 不来
- java - 如何调用基类中存在的参数化构造函数?
- css - 当文本换行时,如何将此图像保持在垂直居中的浮动 div 中?
- yocto - 通过制作新包在 yocto 中添加组件的方法
- java - 递归打印所有路径的树遍历的复杂性
- postgresql - DBeaver,从数据库 Postgres 导出,表结构(属性)到文件 .txt
- javascript - 如何循环此 JSON 字符串以通过特定键获取结果?