【问题标题】:Any-type in Python without automatic coercionPython中的任何类型,没有自动强制
【发布时间】:2021-10-03 00:41:02
【问题描述】:

Python 中的Any-type 是一个类型注释,指定一个值在运行时可以采用的类型不受约束,不能静态确定。 Any 的规则规定:

  • 每种类型都与 Any 兼容,例如
x: int = 8
y: Any = x
  • 任何类型都兼容,例如
x: Any = 8
y: int = x

然而,第二条规则可能会导致一些不合理的行为:

x: Any = 7
y: str = x
# Statically y has the type str, while in runtime it has the type int

这种行为在某些用例中可能有意义。但是,我试图表示外部数据块的类型(例如来自 JSON-API 或 pickle 对象)。将返回类型注释为Any 是有意义的,因为您不知道静态数据将采用什么形式,然后执行isinstance 检查和模式匹配以验证和提取数据的确切形状。然而,这个强制规则使得类型检查器不会验证这些检查是否正确,而是默默地将Any-types 转换为它推断的任何内容,这在运行时通常不是正确的行为。

目前我正在定义该类型在运行时可能具有的所有可能值的Union-type,但这不是一个可持续的解决方案,因为我发现自己不断向Union 添加越来越多的变体。

Python 中是否有类似Any 的类型只有第一个强制规则,而没有第二个?

【问题讨论】:

    标签: python types type-hinting python-typing


    【解决方案1】:

    object 类型是任何类型的有效基,但反之则不然:

    x: int = 8
    y: object = x
    
    x: object = 8
    y: int = x     # error: Incompatible types in assignment (expression has type "object", variable has type "int")
    

    实际上,:object 的使用应该像:Any 一样受到限制。但是,:object 的误用不会悄悄通过,因为object 仅支持所有类型的最小操作:

    x: int = 8
    y: object = x
    
    if isinstance(y, int):
        reveal_type(y)  # note: Revealed type is "builtins.int"
    elif isinstance(y, list):
        reveal_type(y)  # note: Revealed type is "builtins.list[Any]"
    else:
        reveal_type(y)  # note: Revealed type is "builtins.object"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      相关资源
      最近更新 更多