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.
有时在编码时,我需要“特殊类型的字符串”和“特殊类型的整数”作为文档。
例如你可能有。
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.