简体   繁体   English

Python 中的任何类型,无需自动强制

[英]Any-type in Python without automatic coercion

The Any -type in Python is a type annotation specifying that the type a value can take on at runtime is unconstrained and cannot be determined statically. Python 中的Any -type是一个类型注释,指定值在运行时可以采用的类型是不受约束的,不能静态确定。 The rules for Any states that: Any的规则规定:

  • Every type is compatible with Any, eg每种类型都与 Any 兼容,例如
x: int = 8
y: Any = x
  • Any is compatible with every type, eg Any 与每种类型兼容,例如
x: Any = 8
y: int = x

The second rule can however lead to some unsound behaviour:然而,第二条规则可能会导致一些不良行为:

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

This behaviour might make sense in some use cases.在某些用例中,此行为可能有意义。 However, I'm trying to represent the type of an external blob of data (such as from a JSON-API or a pickle object).但是,我试图表示外部数据 blob 的类型(例如来自 JSON-API 或 pickle 对象)。 Annotating the return type as an Any makes sense as you don't know statically what form the data will take, and then doing isinstance checks and pattern matching to validate and extract the exact shape of the data.将返回类型注释为Any是有意义的,因为您不知道静态数据将采用什么形式,然后执行isinstance检查和模式匹配以验证和提取数据的确切形状。 However, this coercion rule makes it so that the type checker will not verify that these checks are correct, but instead silently convert the Any -types to whatever it infers, which often is not the correct behaviour at runtime.然而,这个强制规则使得类型检查器不会验证这些检查是否正确,而是默默地将Any类型转换为它推断的Any类型,这在运行时通常不是正确的行为。

Currently I'm defining a Union -type of all the possible values the type might have at runtime, but this is not a sustainable solution as I find myself constantly adding more and more variants to the Union .目前我正在定义一个类型在运行时可能具有的所有可能值的Union类型,但这不是一个可持续的解决方案,因为我发现自己不断向Union添加越来越多的变体。

Is there any Any -like type in Python which has only the first coercion rule, but not the second? Python 中是否有任何类似Any的类型,它只有第一个强制规则,而没有第二个?

The object type is a valid base for any type but not vice versa: 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")

In practice, usage of :object should be constrained just like :Any .在实践中, :object应该像:Any一样受到限制。 However, misuse of :object does not pass silently as object supports only the minimum operations of all types:然而,滥用: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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM