【问题标题】:What's the difference between a constrained TypeVar and a Union?受约束的 TypeVar 和 Union 有什么区别?
【发布时间】:2020-03-13 04:38:48
【问题描述】:

如果我想要一个可以是多种可能类型的类型,Unions 似乎是我的表达方式:

U = Union[int, str] 

U 可以是intstr

我注意到虽然TypeVars 允许可选的 var-arg 参数,但它们似乎也做同样的事情:

T = TypeVar("T", int, str)

TU 似乎都只允许使用 strint 类型。

这两种方式有什么区别,什么时候应该首选?

【问题讨论】:

标签: python type-hinting python-typing union-types type-variables


【解决方案1】:

T 的类型必须在给定scope 内的多次使用中保持一致,而U 则不然。

使用Union 类型作为函数参数,参数和返回类型都可以不同:

U = Union[int, str]

def union_f(arg1: U, arg2: U) -> U:
    return arg1

x = union_f(1, "b")  # No error due to different types
x = union_f(1, 2)  # Also no error
x = union_f("a", 2)  # Also no error
x # And it can't tell in any of the cases if 'x' is an int or string

将其与参数类型必须匹配的TypeVar 进行比较:

T = TypeVar("T", int, str)

def typevar_f(arg1: T, arg2: T) -> T:
    return arg1

y = typevar_f(1, "b")  # "Expected type 'int' (matched generic type 'T'), got 'str' instead
y = typevar_f("a", 2)  # "Expected type 'str' (matched generic type 'T'), got 'int' instead

y = typevar_f("a", "b")  # No error
y  # It knows that 'y' is a string

y = typevar_f(1, 2)  # No error
y  # It knows that 'y' is an int

因此,如果允许多种类型,请使用TypeVar,但在单个范围内T 的不同用法必须相互匹配。如果允许多种类型,则使用Union,但在给定范围内U 的不同用法不需要​​相互匹配。

【讨论】:

  • 在这种情况下,任何人都可以详细说明“在单一范围内”的含义吗?具体来说,如果我是“外部范围”(模块或类或其他)并且我声明了一个 TypeVar,并且我在两个不同的函数中使用了该类型,那么 var 的用法是否必须与两个内部范围匹配(功能)单独,还是跨越整个外部范围?如果我有嵌套函数怎么办?
  • @ShapeOfMatter 请注意我在顶部链接到的 PEP 部分。它进入了相当深入的细节。
  • @ShapeOfMatter 如果T 是在任何函数之外定义的,则它的类型可能因函数而异,除非这些函数是方法,并且包含它们的类是T 上的Generic
猜你喜欢
  • 2020-03-04
  • 1970-01-01
  • 2010-10-28
  • 2013-03-18
相关资源
最近更新 更多