如何在不明确列出类型的情况下确保参数具有相同的类型? [英] How can I ensure that arguments have same type without listing the types explicitly?

查看:52
本文介绍了如何在不明确列出类型的情况下确保参数具有相同的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我们需要一个接受任何类型的两个参数的函数,只要这两个参数具有相同的类型.您将如何使用 mypy 静态检查它?

Let us assume that we need a function that accepts two arguments of any type as long as both arguments have the same type. How would you check it statically with mypy?

如果我们只需要函数接受一些有限数量的已知类型,这很容易:

If we only need the function to accept some finite amount of already known types, it is easy:

from typing import TypeVar, List, Callable

T = TypeVar('T', int, str, List[int], Callable[[], int])

def f(a: T, b: T) -> None:
   pass

f(1, 2)
f("1", "2")
f([1], [2])
f(lambda: 1, lambda: 2)
f(1, "2") # mypy will print an error message

对于这段代码,mypy 可以确保 f 的参数是两个 int 或两个 str 或两个 ints 或两个返回 int 的零参数函数.

For this code, mypy can ensure that the arguments to f are either two ints or two strs or two lists of ints or two functions of zero arguments that return int.

但是如果我们事先不知道类型怎么办?如果我们需要类似于 F# 和 OCaml 中的 let f (a:'t) (b:'t) = () 怎么办?简单地编写 T = TypeVar('T') 会使 f(1, "2") 之类的东西有效,这不是我们想要的.

But what if we don't know the types in advance? What if we need something similar to let f (a:'t) (b:'t) = () from F# and OCaml? Simply writing T = TypeVar('T') would make things like f(1, "2") valid, and this is not what we want.

推荐答案

你所要求的是不可能的(见下文解释).但通常,python 中不需要要求两个参数具有完全相同的类型.

What you're asking for is impossible (see below for explanation). But usually, there's no need in python to require that two arguments have precisely identical type.

在您的示例中,intstrList[int]Callable[[], int] 没有任何通用的方法或属性(除了任何两个 object 实例所具有的),所以除非你用 isinstance 手动检查类型,否则你真的不能用你的参数做任何你不能用 object 实例做的事情.你能解释一下你的用例吗?

In your example, int, str, List[int], Callable[[], int] don't have any common methods or attributes (other than what any two object instances have), so unless you manually check the type with isinstance, you can't really do anything with your argument that you couldn't do with object instances. Could you explain your use case?

Mypy 类型系统具有子类型.所以当你写f(a, b)时,mypy只检查ab的类型都是T<的子类型/code> 而不是精确等于 T.

Mypy type system has subtyping. So when you write f(a, b), mypy only checks that types of a and b are both subtypes of T rather than precisely equal to T.

此外,mypy 的子类型系统大多是预定义的,不受程序员控制,特别是每个类型都是 object 的子类型.(IIUC,在 OCaml 中程序员需要明确说明哪些类型应该处于子类型关系中,因此默认情况下每个类型约束都是等式约束.这就是为什么你可以在 OCaml 中做你想做的事).

In addition mypy subtyping system is mostly pre-defined and not under the programmer control, in particular every type is a subtype of object. (IIUC, in OCaml the programmer needs to say explicitly which types should be in a subtyping relationship, so by default every type constraint is equality constraint. That's why you could do what you wanted in OCaml).

所以,当你写

T = TypeVar('T')
f(a: T, b: T) -> None: ...
f(x, y)

你只是告诉 mypy xy 的类型必须是某个普通类型 T 的子类型.当然,通过推断 Tobject 总是(简单地)满足这个约束.

you are only telling mypy that the types of x and y must be subtypes of some common type T. And of course, this constraint is always (trivially) satisfied by inferring that T is object.

更新

对于您在评论中的问题(是否可以确保 y 的类型是 x 类型的子类型?),答案是否定的.

To your question in the comment (is it possible to ensure that type of y is of subtype of type of x?), the answer is also no.

即使 mypy 允许一个类型变量从上面被指定的类型绑定,这个绑定不能是另一个类型变量,所以这行不通:

Even though mypy allows a type variable to be bounded from above by a specified type, that bound cannot be another type variable, so this won't work:

T = TypeVar('T')
U = TypeVar('U', bound=T, contravariant=True) # error, T not valid here
f(x: T, y: U) -> None

这篇关于如何在不明确列出类型的情况下确保参数具有相同的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆