【问题标题】:Python type hint for Callable with variable number of str/same type arguments?具有可变数量的str /相同类型参数的可调用的Python类型提示?
【发布时间】:2019-08-26 13:28:09
【问题描述】:

如何为所有这些可调用对象指定一种类型:

a(str)
b(str, str)
c(str, str, str)
d(str, str, str, str

我发现我可以用一般的方式指定Callable[..., None],但是如何详细指定所有参数都是str而不用丑陋的语法Union[Callable[[str], None], Callable[[str, str], None, __more_like_this__]。是其他方法吗?我可以用打字来做吗?

【问题讨论】:

  • 那么它有什么难看的呢?我看不出您想对其进行哪些更改以使其不那么“丑陋”
  • 你有四个函数,每个函数都有一个非常特定的,不同的类型。工会是唯一的出路。 (例如,a 不属于可以接受 1-4 个str 参数的函数类型;它属于完全接受一个参数的函数类型。)跨度>
  • @chepner 也许你是对的 - 不支持 *args 或不需要支持。
  • 我试图按照我的评论提供答案;如果您认为我遗漏了应该解决的问题(例如,可能是您认为应该考虑的第三种类型 t3),请发表评论。
  • 您要输入提示 1-4 str 参数,还是 任何 个 str 参数?

标签: python python-3.x python-typing


【解决方案1】:

您可以使用callback protocol 指定带有可变字符串参数的函数类型:

from typing_extensions import Protocol


class Callback(Protocol):
    def __call__(self, *args: str) -> None: ...

并像这样使用它:

def handler(cb: Callback) -> None:
    cb('a', 'b', 'c')

def callback(*args: str) -> None:
    pass

handler(callback)

请注意,回调必须采用可变参数,例如。这行不通:

def callback(a: str, b: str) -> None:
    pass

协议已在 Python 3.8 中添加到标准库 typing 模块中,因此如果您想在 Python 3.5-3.7 上使用它们,则需要从 PyPI 安装 typing-extensions 模块。

【讨论】:

    【解决方案2】:

    您想要的是 4 种不同类型的联合。

    t1 = Union[
     Callable[[str],Any],
     Callable[[str,str],Any],
     Callable[[str,str,str],Any],
     Callable[[str,str,str,str],Any],
    ]
    

    与可以接受 1 到 4 个参数的函数类型进行对比:

    t2 = Callable[[str,Optional[str],Optional[str],Optional[str]],Any]
    

    类似的函数

    def foo(x: str, y:str):
    

    不属于上述第二种。如果我说我需要一个t2 类型的函数,你不知道我可能会尝试传递多少个参数。我可以给你foo,但是你可能会尝试传递 3 个参数,或者只传递 1 个参数,然后得到一个 TypeError。

    如果您要求t1 类型的函数,我可以给您foo。 t1 不 承诺t1 中的所有值都可以多于或少于 3 个参数;它只包含做的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 2021-07-10
      相关资源
      最近更新 更多