gpt4 book ai didi

python - 如何为可使用任意数量的 Any 类型的关键字参数调用的类型定义 Python 协议(protocol)?

转载 作者:行者123 更新时间:2023-12-03 08:18:49 25 4
gpt4 key购买 nike

如何为以下类型定义 Python 协议(protocol):

  • 可调用
  • 具有任意数量、任意类型的关键字参数
  • 返回指定类型的值

这是我的尝试:

from typing import Any, Protocol, TypeVar

T = TypeVar("T", covariant=True)


class Operation(Protocol[T]):
def __call__(self, **kwargs: Any) -> T:
pass


# some example functions that should be a structural sub-type of "Operation[str]"
def sumint(*, x: Any, y: Any) -> str:
return f"{x} + {y} = {x + y}"


def greet(*, name: Any = "World") -> str:
return f"Hello {name}"


# an example function that takes an "Operation[str]" as an argument
def apply_operation(operation: Operation[str], **kwargs: Any) -> str:
return operation(**kwargs)


if __name__ == "__main__":
print(apply_operation(sumint, x=2, y=2))
# prints: 2 + 2 = 4
print(apply_operation(greet, name="Stack"))
# prints: Hello Stack

但是,mypy 会产生错误:

example.py:26: error: Argument 1 to "apply_operation" has incompatible type "Callable[[NamedArg(Any, 'x'), NamedArg(Any, 'y')], str]"; expected "Operation[str]"
example.py:28: error: Argument 1 to "apply_operation" has incompatible type "Callable[[DefaultNamedArg(Any, 'name')], str]"; expected "Operation[str]"
Found 2 errors in 1 file (checked 1 source file)

我做错了什么?如何让 MyPy 开心?

最佳答案

您无法定义适合您要求的协议(protocol),因为从静态类型角度来看它根本上是不安全的。

这里的问题是,虽然你说 Operation[T] 的一个实例应该可以“使用任何数量的任何类型的关键字参数”进行调用,您似乎实际上意味着它接受一些关键字参数的组合。它不仅仅接受任何关键字参数。

如果你可以定义一个 Operation[T]具有您想要的特性的协议(protocol),然后是您的apply_operation

def apply_operation(operation: Operation[str], **kwargs: Any) -> str:
return operation(**kwargs)

仍然是一个类型错误。 operation(**kwargs)是不安全的,因为不能保证提供的关键字参数是参数 operation接受。你可以打电话

apply_operation(sumint, name="Stack")

这将适合 apply_operation签名,但这仍然是一个不安全的调用。


如果你想对此进行注释,最好的选择可能是使用 Callable[..., T] ,正如 Alex Waygood 的回答中所建议的。指定...作为 Callable 的参数类型列表有效地禁用可调用参数的类型检查,就像用 Any 注释变量一样有效地禁用该变量的类型检查。

请记住,这会禁用安全检查 - 如果您执行类似 apply_operation(sumint, name="Stack") 的操作,则不会发出警告。 .

关于python - 如何为可使用任意数量的 Any 类型的关键字参数调用的类型定义 Python 协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68499904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com