【问题标题】:Is there an equivalent of typedefs for mypy?mypy 是否有等效的 typedef?
【发布时间】:2023-03-04 20:03:01
【问题描述】:

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

例如你可能有。

def make_url(name:str) -> URL:

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

URL = str

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

class URL(str):
    pass

甚至

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

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

【问题讨论】:

  • 您的意思是alias?您可以只写URL = str,并使用URL 作为类型。还是您的意思是协议之类的东西?
  • "在 python 中你可以做类似URL = str"的事情——这行得通吗?如果你已经知道用 Python 做什么,你的问题是什么?
  • @khelwood 我想如果有一种公认的方法我很感兴趣。我的理解是使用URL = str 并不完全是另一种类型。如果类型系统允许您从字符串中为 URL 分配 url,但要求您对采用 URL 的函数的参数进行注释,这可能会很方便。

标签: python typedef mypy


【解决方案1】:

您可以使用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) 不会创建新类或引入超出常规函数调用的任何开销。

【讨论】:

  • 啊哈,这似乎正是我在感谢之后的样子。我刚刚在跟进 MrBean 的别名建议时发现了这个,看起来就是这样。
  • 似乎有a new way of doing this in python 3.10 提示输入系统。例如,Alias: TypeAlias = List[str]
  • 我认为Alias 不会自动帮助您捕获错误。它有助于提高可读性,但与 NewType 不同,如果您只是说 URL: TypeAlias = str 然后尝试使用非 url 字符串,它会很好地传递 MyPy。
猜你喜欢
  • 2010-11-14
  • 1970-01-01
  • 2011-08-28
  • 2012-10-20
  • 2011-04-05
  • 1970-01-01
  • 2021-01-03
  • 2016-10-26
相关资源
最近更新 更多