【问题标题】:Function for getting type of TypedDict value that works with static type checker用于获取与静态类型检查器一起使用的 TypedDict 值类型的函数
【发布时间】:2020-12-15 02:07:35
【问题描述】:

我正在寻找一个 Python (3.8+) 函数:

  • 输入:TypedDict 的键
  • 输出:
    • 返回值(简单)
    • 是否有适当的类型提示(我被卡住的地方)

这里有一个代码示例来帮助解释:

from typing import Any, Literal, TypedDict

class Foo(TypedDict):
    bar: int
    baz: str
    spam: Any

foo = Foo(bar=0, baz="hi", spam=1.0)

def get_type(key: Literal["bar", "baz"]):  # How to type hint the return here?
    """Function that get TypedDict's value when passed a key."""
    val = foo[key]
    # This works via intelligent indexing
    # SEE: https://mypy.readthedocs.io/en/stable/literal_types.html#intelligent-indexing
    reveal_type(val)  # mypy: Revealed type is 'Union[builtins.int, builtins.str]'
    return val

fetched_type = get_type("bar")
reveal_type(fetched_type)  # mypy: Revealed type is 'Any'
# I would like this to have output: 'int'

如果你看不出来,我使用的静态类型检查器是mypy

我在get_type 上面的函数在intelligent indexing 中实现了一半,但我不知道如何键入提示get_type 的返回。

返回get_type应该输入什么类型的提示?


研究

这两个问题

使用TypeVar 提供答案。有什么方法可以将TypeVarTypedDict 一起使用?

【问题讨论】:

    标签: python dictionary mypy python-typing


    【解决方案1】:

    如果我正确理解您的问题,您可以将@overload 用于get_type

    from typing import Any, Literal, TypedDict, Union, overload
    
    class Foo(TypedDict):
        bar: int
        baz: str
        spam: Any
    
    foo = Foo(bar=0, baz="hi", spam=1.0)
    
    
    @overload
    def get_type(key: Literal["bar"]) -> int: ...
    
    @overload
    def get_type(key: Literal["baz"]) -> str: ...
        
    
    def get_type(key: Literal["bar", "baz"]) -> Union[int, str]:
        """Function that get TypedDict's value when passed a key."""
        val = foo[key]
        reveal_type(val)  # mypy: Revealed type is 'Union[builtins.int, builtins.str]'
        return val
    
    fetched_type = get_type("bar")
    reveal_type(fetched_type)  # mypy: Revealed type is 'builtins.int'
    
    

    【讨论】:

    • 非常感谢@alex_noname,这行得通!在我的实际用例TypedDict 中,有很多键。使用这种方案,get_type方法的overloads相当多,不会有“轻量级”的感觉。在标记答案之前,我会坚持下去,以防有不那么冗长的解决问题的方法。
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多