为什么Python类型提示有时会降低IDE推荐质量?
我正在进行一个练习,想在一大堆代码中添加类型提示,但有时候我发现,添加的类型提示并不理想,反而让IDE的建议变得更差。
之前,IDE能够判断出y['result']是一个字符串:
但现在,它就不知道了:
我知道我可以通过更具体的类型提示来解决这个问题:
但一般来说,有没有办法知道添加的类型提示是否比LSP(语言服务器协议)从代码中推断出的更不具体呢?
我尝试添加非常详细的类型提示来避免这个问题(比如,子类化TypeDict),但如果LSP能够自己推断出内容,我就不想花那么多精力。
我想知道有没有办法在用户添加的类型提示会让LSP对代码的理解变差时给出警告:
当类型提示与代码相矛盾时,我们会收到警告:
我希望能有一种警告,当类型提示比没有类型提示还要糟糕时能提醒我。
你可以看到,LSP很容易就能推断出一个相当详细的返回类型。
如果用户添加了一个“糟糕”的类型提示,这些信息就会丢失。
不过我接受整体反馈。也许这更像是对
2 个回答
dict
就相当于 dict[Any, Any]
。在类型提示中,提示总是优先于推断,所以你把 y['result']
的类型从可以推断为 str
,变成了明确说明它的类型是 Any
。
解决这个问题的方法通常跟工具有关。举个例子,mypy
有一个选项 --disallow-any-generic
,这个选项会把单独使用 dict
标记为错误。使用这个选项时,通用类型必须有明确的“参数”,来说明这些参数是如何绑定的。如果你真的想用 dict[Any, Any]
,你可以这样写,但你不能简单地用 dict
来代替它。
不,目前类型检查器无法告诉你你的提示是否会让LSP(语言服务器协议)理解得更糟。在你提到的Visual Studio Code(它底层使用了Pyright)和mypy的例子中都是这样。
虽然理论上类型检查器可以实现这个功能,但如果需要这个功能,那就是个警告。这是因为你的LSP应该根据函数的接口(返回类型)来提供建议,而不是根据实现(函数的具体内容)。否则,当你使用的函数的实现发生变化时,即使它的行为保持不变,你的LSP提供的建议也可能会出错!
你说:
我正在通过一个大型代码库添加类型提示。
如果你想确保你的LSP对代码的理解保持最佳状态,你应该只在其他模块/包使用的函数上添加类型提示。这样可以最大程度地发挥类型提示的好处(为其他团队成员或你的服务使用者建立一个接口)。
至于私有函数,你暂时不需要添加类型提示。这让你可以把它们的实现当作接口来处理,这对内部代码来说并不是个坏主意。你遇到的类型提示带来的问题(意外地从接口中移除信息的风险)也就被推迟了。