首页 > 解决方案 > mypy 是否有等效的 typedef?

问题描述

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

例如你可能有。

def make_url(name:str) -> URL:

whereURL真的是一个字符串。在某些语言(例如 C)中,您可以为此使用 typedef,而在 python 中,您可以执行类似的操作。

URL = str

有没有正确的方法来做到这一点?您可以以非常程序化的方式做事,并拥有:

class URL(str):
    pass

甚至

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

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

标签: pythontypedefmypy

解决方案


您可以使用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

注意几点:

静态类型检查器会将新类型视为原始类型的子类。这有助于捕获逻辑错误 [...]

请注意,这些检查仅由静态类型检查器强制执行。在运行时,语句 Derived = NewType('Derived', Base) 将使 Derived 成为一个函数,该函数会立即返回您传递给它的任何参数。这意味着表达式 Derived(some_value) 不会创建新类或引入超出常规函数调用的任何开销。


推荐阅读