gpt4 book ai didi

python - 如何为类型参数设置 python 类型

转载 作者:行者123 更新时间:2023-12-01 06:21:12 29 4
gpt4 key购买 nike

我想为作为参数传递的 Python 类型正确添加类型。例如。让我们假设我们想向以下函数添加类型:

def do_something_based_on_types(
...
type_name: str,
str_to_type_mapping: Dict[str, Any], # what instead of Any?
):
...
object = str_to_type_mapping[type_name]()
...

我们想要传递来自 str 的映射。键入基于我们想要构造所选类的对象的类型。对于这种情况,正确的键入是什么(而不是代码示例中使用的 Any)。

最佳答案

你的例子非常动态。由于 Python 类型注释的主要目的是支持静态分析,因此它们可以为我们提供的功能是有限的。不过,我确实认为我们可以做得比 Any 更好。 !

(注意:为了防止混淆,我会将代码片段中名为 object 的变量称为 my_object ,当我使用 object 时,我指的是 Python 类型)。

使用 typing.Type

由于您提到提供的字典中的值应该是可以启动的类型,因此合理的类型注释可以是 Dict[str, Type[object]]Dict[str, Type] ,其中后者相当于 Dict[str, Type[Any]] 。第一个是最严格的,它将限制类型检查器允许您在 my_object 上执行的操作。多变的。第二个仅比普通的 Any 稍好一些。 ,尽管当调用者意外提供实例而不是类型时,它会警告调用者。

typing.Callable

根据您提供的代码片段,使用字典值的唯一方法是创建一个新实例。类型并不是唯一可以做到这一点的东西。实际上,任何采用零参数并返回对象的可调用函数(普通函数、类方法)也足够了。所以使用Callable[[], object]将为函数的调用者提供更大的灵活性,并且在传递不具有零参数构造函数的类型时发出警告。我更喜欢这个而不是 Type因为它看起来更安全,也更符合 Python 鸭子类型的精神。

比普通对象更好的东西?

这两种解决方案都有一个限制,即在您的函数内部,我们对 my_object 的类型一无所知。 。在一般情况下,我们“被迫”做isinstance每次我们执行对象类型不支持的操作时都会进行检查。但是,也许在您的用例中,单个字典不应该只包含任何类型。可能是这样的:

  1. 所有类型都有一个共同的基类,例如 MyBase .
  2. 所有类型都应该支持一组通用的操作(方法或属性)。

对于情况(1),我们可以替换 object输入类型 MyBase 。类型检查器应该能够执行 MyBase 支持的操作使用安全,并在提供的字典包含其他类型时发出警告。

对于情况 (2), typing.Protocol 可以帮助我们。您可以使用所需的操作定义自定义协议(protocol),并将其添加到类型注释中:

class MyCustomProto(Protocol):
foo: int
def bar(self) -> str: ...

现在类型检查器应该知道 my_object应该具有整数属性 foo和一个方法bar返回一个字符串。请注意Protocol已添加到 Python 3.8,并且可通过 typing-extensions 适用于以前的版本包。

字典与打字。映射

与你的问题没有直接关系,但如果你只使用字典阅读,你应该考虑替换 DictMapping类型。这允许调用者提供除 dict 子类之外的任何映射类型(实际上不太可能发生)。但更重要的是,它会在意外修改提供的映射时向您发出警告,这可能会导致难以发现错误。因此,我的最终建议是 Mapping[str, Callable[[], <X>] ,与 <X>object 之一, MyCustomProtoMyBase .

关于python - 如何为类型参数设置 python 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60343591/

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