PEP 484:类型提示的独占类型 [英] PEP 484: exclusive type for type hint

查看:86
本文介绍了PEP 484:类型提示的独占类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Could I specify exclusive type? Something like this:

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

推荐答案

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

PEP 484 does not include a built-in way of specifying a "blacklisted" type.

做那种事情通常没有什么意义——我能想到为什么你可能想要做这样的事情的唯一原因是如果你想区分 strIterable[str]Sequence[str] 以某种方式.如果是这样的话,不幸的是,PEP 484 没有办法让你这样做 -- str,无论好坏,都是这两种类型的合法子类.

Doing that kind of thing typically doesn't really make sense -- the only reason I can think of why you might want to do something like this is if you wanted to distinguish between str and Iterable[str] or Sequence[str] in some fashion. If that's the case, PEP 484 unfortunately doesn't have a way of letting you do this -- str, for better or for worse, is a legitimate subclass of those two types.

在这种情况下,您最好的办法是修改您的类型签名以区分 strList[str] 哪些 是合法可区分的类.不理想,但总比没有好.

Your best bet in this case is to modify your type signature to distinguish between str and List[str] which are legitimately distinguishable classes. Not ideal, but better then nothing.

也就是说,如果你真的想做这样的事情,那么这样做是有可能的,假设你使用的是 mypy 并且不介意诉诸肮脏的黑客.

That said, if you really do want to do something like this, it's sort of possible to do so, assuming you're using mypy and don't mind resorting to dirty hacks.

一个技巧是基本上修改你的 foo 函数,让它总是返回一些东西并滥用 overload 和非严格可选模式的语义,就像这样:

One hack is to basically modify your foo function so it always returns something and abuse overload and the semantics of non-strict optional mode, like so:

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

如果您尝试在没有 --strict-optional 标记的 mypy 中运行它,mypy 将用 "foo" 不返回值 错误标记最后一行.然后,您需要记住出现此错误消息是因为您传入了一个字符串参数.您还需要记住始终将 foo 函数的输出分配给一个值.

If you try running this in mypy WITHOUT the --strict-optional tag, mypy will flag the last line with a "foo" does not return a value error. You would then need to remember that this error message occurs because you passed in a string argument. You would also need to remember to always assign the output of your foo function to a value.

(如果您确实启用了严格可选,mypy 会抱怨您的两个重载具有不兼容的签名.)

(If you do enable strict-optional, mypy will complain that your two overloads have incompatible signatures.)

我们在这里主要做的是:

What we're basically doing here is:

  1. 利用禁用严格可选的事实,None 是每种类型的合法值(因此重载是合法的)
  2. 利用 mypy 会(作为额外福利)在您从不返回任何内容的函数中分配值的情况下警告您这一事实.
  1. Exploiting the fact that with strict-optional disabled, None is a legal value of every type (so the overload is legal)
  2. Exploiting the fact that mypy will (as an extra perk) warn you of cases where you assign a value from a function that doesn't return anything.

这一切都太老套了,很可能是个坏主意.我也不保证这种互动在未来会继续有效.

This is all pretty hacky and very likely a bad idea. I also make no promises that this interaction will continue to work in the future.

您可以尝试的第二个技巧是编写一个 mypy 插件来捕获您的特定案例的实例.在撰写本文时,mypy 插件系统是一项未记录、暂定且极易更改的功能,但如果您真的想这样做,则可能需要进行调查.

The second hack you could try is to write a mypy plugin to catch instances of your specific case. The mypy plugin system is, as of time of writing, an undocumented, tentative, and highly-prone-to-change feature, but if you really want to do this, that might be something to investigate.

如果您特别想区分 strSequence[str]Iterable[str](或类似的东西),您可以尝试的其他方法是:

If you're specifically trying to distinguish between str and Sequence[str] or Iterable[str] (or something similar), something else you can try is to:

  1. 创建 Typeshed 和/或打字模块的自定义分支
  2. 修改 str 的类定义/存根,使其不会从 Sequence[str]Iterable[str] 继承(或者添加幻影类型什么的)
  3. 使用 --custom-typeshed-dir--custom-typing 命令行参数使 mypy 使用您的自定义类型定义.
  1. Create a custom fork of Typeshed and/or the typing module
  2. Modify the class definition/stubs for str so it doesn't inherit from either Sequence[str] or Iterable[str] (or add phantom types or something)
  3. Make mypy use your custom type definitions using the --custom-typeshed-dir and --custom-typing command line arguments.

基本上,如果默认类型层次结构不是您想要的,请发明一个自定义层次结构.

Basically, if the default type hierarchy isn't quite what you want, invent a custom one.

当然,如果您正在使用其他一些符合 PEP 484 的检查器(例如 Pycharm 的内置检查器),那么您可能就不走运了.

Of course, if you're using some other PEP 484 compliant checker (such as Pycharm's built in checker), you're probably out of luck.

这篇关于PEP 484:类型提示的独占类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆