Python typing: Pylance不显示输入类型

huangapple go评论238阅读模式
英文:

Python typing: pylance doesn't show input types

问题

以下是您要翻译的内容:

  1. 我正在尝试为任何可调用对象创建包装器以下是最小示例
  2. from typing import Any, TypeVar, Generic, Callable
  3. ReturnType = TypeVar("ReturnType", bound=Any)
  4. CallableType = Callable[..., ReturnType]
  5. class Wrapper(Generic[ReturnType]):
  6. def __init__(self, callable_: CallableType[ReturnType]) -> None:
  7. self.callable_ = callable_
  8. def __call__(self, *args: Any, **kwargs: Any) -> ReturnType:
  9. return self.callable_(*args, **kwargs)
  10. class Action:
  11. def __init__(self, title: str) -> None:
  12. """docstring"""
  13. self.title = title
  14. wrapped = Wrapper(Action)
  15. action = wrapped("title")
  16. Pylance 可以理解 `action` 的类型是 `Action`但我看不到 `__init__` 文档字符串和所需的参数
  17. 期望的行为
  18. 我做错了什么如何修复
英文:

I'm trying to do "wrapper" class for any callable. Here is minimal example:

  1. from typing import Any, TypeVar, Generic, Callable
  2. ReturnType = TypeVar("ReturnType", bound=Any)
  3. CallableType = Callable[..., ReturnT]
  4. class Wrapper(Generic[ReturnType]):
  5. def __init__(self, callable_: CallableType[ReturnType]) -> None:
  6. self.callable_ = callable_
  7. def __call__(self, *args: Any, **kwargs: Any) -> ReturnType:
  8. return self.callable_(*args, **kwargs)
  9. class Action:
  10. def __init__(self, title: str) -> None:
  11. """docstring"""
  12. self.title = title
  13. wrapped = Wrapper(Action)
  14. action = wrapped("title")

Pylance can understand, that action type is Action, but I can't see __init__ docsting and needed arguments:Python typing: Pylance不显示输入类型

Desired behaviour:Python typing: Pylance不显示输入类型

What do I do wrong and how can I fix it?

答案1

得分: 1

你已经用Any注释了你的__call__方法,但Pyright不会根据你的使用情况来限制这些Any的更具体类型。你需要使用ParamSpec来捕获可接受为参数的可调用对象的参数(类似于你如何使用TypeVar来捕获返回类型)。

  1. from typing import Any, TypeVar, ParamSpec, Generic, Callable
  2. Params = ParamSpec("Params")
  3. ReturnType = TypeVar("ReturnType")
  4. class Wrapper(Generic[Params, ReturnType]):
  5. def __init__(self, callable_: Callable[Params, ReturnType]) -> None:
  6. self.callable_ = callable_
  7. def __call__(self, *args: Params.args, **kwargs: Params.kwargs) -> ReturnType:
  8. return self.callable_(*args, **kwargs)
  9. class Action:
  10. def __init__(self, title: str) -> None:
  11. """docstring"""
  12. self.title = title
  13. wrapped = Wrapper(Action)
  14. action = wrapped("title")

注意1:如果你使用的是Python < 3.10,你需要从typing_extensions中导入ParamSpec

注意2:你不需要传递bound=Any给TypeVar,因为那基本上是默认的。传递bound=Any不会改变任何东西。

英文:

You've annotated your __call__ with Any. Pyright doesn't restrict these Any to more narrow types just based on your usage. You'll need to use a ParamSpec to capture the parameters of the callable you accept as the argument (similar how you capture the return type with a TypeVar).

  1. from typing import Any, TypeVar, ParamSpec, Generic, Callable
  2. Params = ParamSpec(&quot;Params&quot;)
  3. ReturnType = TypeVar(&quot;ReturnType&quot;)
  4. class Wrapper(Generic[Params, ReturnType]):
  5. def __init__(self, callable_: Callable[Params, ReturnType]) -&gt; None:
  6. self.callable_ = callable_
  7. def __call__(self, *args: Params.args, **kwargs: Params.kwargs) -&gt; ReturnType:
  8. return self.callable_(*args, **kwargs)
  9. class Action:
  10. def __init__(self, title: str) -&gt; None:
  11. &quot;&quot;&quot;docstring&quot;&quot;&quot;
  12. self.title = title
  13. wrapped = Wrapper(Action)
  14. action = wrapped(&quot;title&quot;)

Note1: If you're using python<3.10 you'll need to import ParamSpec from typing_extensions.

Note2: You don't need to pass a bound=Any to the TypeVar as that's (more or less) the default anyway. Passing bound=Any doesn't change anything nevertheless.

huangapple
  • 本文由 发表于 2023年6月26日 19:17:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556174.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定