mypy 是否有等效的 typedef?

Is there an equivalent of typedefs for mypy?

有时在编码时,我需要“特殊类型的字符串”和“特殊类型的整数”作为文档。

例如你可能有。

def make_url(name:str) -> URL:

其中 URL 实际上是一个字符串。在某些语言中,例如 C,您可以为此使用 typedef,而在 python 中,您可以做类似的事情。

URL = str

有正确的方法吗?您可以以非常编程的方式做事,并且:

class URL(str):
    pass

甚至

class URL:
    def __init__(self, url):
        self.url

但是这两种感觉都太过分了,以至于对于很多用例来说,它们并不值得开销。

您可以使用 NewType 辅助函数来创建新类型。 这是一个小例子:

from typing import NewType

UserId = NewType('UserId', int)
some_id = UserId(524313)

def foo(a: UserId):
    pass

def bar(a: int):
    pass

foo(some_id)  # OK
foo(42)  # error: Argument 1 to "foo" has incompatible type "int"; expected "UserId"
bar(some_id)  # OK

注意几点:

The static type checker will treat the new type as if it were a subclass of the original type. This is useful in helping catch logical errors [...]

Note that these checks are enforced only by the static type checker. At runtime, the statement Derived = NewType('Derived', Base) will make Derived a function that immediately returns whatever parameter you pass it. That means the expression Derived(some_value) does not create a new class or introduce any overhead beyond that of a regular function call.