PEP 484:类型提示的独占类型

时间:2017-09-20 05:22:08

标签: python python-3.5 type-hinting

我可以指定独占类型吗?像这样:

def foo(bar: Not[str]) -> None:
    assert not isinstance(bar, str)
    print(type(bar))

1 个答案:

答案 0 :(得分:0)

PEP 484不包含指定"黑名单"的内置方式。类型。

做这种事情通常没有意义 - 我能想到为什么你可能想做这样的事情的唯一原因是你想要区分str和{{ 1}}或Iterable[str]以某种方式。如果是这样的话,不幸的是,PEP 484 doesn't have a way of letting you do this - str,无论好坏,都是这两种类型的合法子类。

在这种情况下,您最好的选择是修改您的类型签名,以区分{em} 合法可分辨类的Sequence[str]str。不理想,但没有更好。

也就是说,如果你真的想做这样的事情,那么可以这样做,假设你使用mypy并且不介意使用脏黑客。< / p>

一个hack基本上是修改你的List[str]函数,所以它总是返回一些东西并滥用foo和非严格可选模式的语义,如下所示:

overload

如果您尝试在mypy中运行此项而不使用from typing import overload, Optional @overload def foo(bar: str) -> None: ... # Alternatively, replace "object" below # with the types you *do* want to allow @overload def foo(bar: object) -> int: ... def foo(bar: object) -> Optional[int]: assert not isinstance(bar, str) print(type(bar)) return 0 def main() -> None: x = 0 x = foo(3) # typechecks x = foo("foo") # fails 标记,则mypy会标记最后一行,并显示--strict-optional错误。然后,您需要记住发生此错误消息,因为您传入了字符串参数。您还需要记住始终将"foo" does not return a value函数的输出分配给值。

(如果您启用了strict-optional,mypy会抱怨您的两个重载具有不兼容的签名。)

我们在这里基本上做的是:

  1. 利用严格可选禁用的事实,foo是每种类型的合法值(因此重载是合法的)
  2. 利用mypy(作为额外的振作)警告你从一个不返回任何东西的函数中分配值的事实。
  3. 这一切都非常hacky,很可能是一个坏主意。我也不承诺这种互动将来会继续发挥作用。

    你可以尝试的第二个黑客是编写一个mypy插件来捕获你特定情况的实例。截至撰写本文时,mypy插件系统是一个未记录的,暂定的且极易发生变化的功能,但如果你真的想这样做,可能需要调查。

    如果您专门尝试区分NonestrSequence[str](或类似内容),您可以尝试的其他方法是:

    1. 创建Typeshed的自定义分支和/或输入模块
    2. 修改Iterable[str]的类定义/存根,使其不会从strSequence[str]继承(或添加幻像类型或其他内容)
    3. 使用Iterable[str]--custom-typeshed-dir命令行参数使mypy使用您的自定义类型定义。
    4. 基本上,如果默认类型层次结构不是你想要的,那就发明一个自定义层次结构。

      当然,如果您正在使用其他符合PEP 484标准的检查程序(例如Pycharm内置的检查程序),您可能运气不佳。