我可以指定独占类型吗?像这样:
def foo(bar: Not[str]) -> None:
assert not isinstance(bar, str)
print(type(bar))
答案 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会抱怨您的两个重载具有不兼容的签名。)
我们在这里基本上做的是:
foo
是每种类型的合法值(因此重载是合法的)这一切都非常hacky,很可能是一个坏主意。我也不承诺这种互动将来会继续发挥作用。
你可以尝试的第二个黑客是编写一个mypy插件来捕获你特定情况的实例。截至撰写本文时,mypy插件系统是一个未记录的,暂定的且极易发生变化的功能,但如果你真的想这样做,可能需要调查。
如果您专门尝试区分None
和str
或Sequence[str]
(或类似内容),您可以尝试的其他方法是:
Iterable[str]
的类定义/存根,使其不会从str
或Sequence[str]
继承(或添加幻像类型或其他内容)Iterable[str]
和--custom-typeshed-dir
命令行参数使mypy使用您的自定义类型定义。基本上,如果默认类型层次结构不是你想要的,那就发明一个自定义层次结构。
当然,如果您正在使用其他符合PEP 484标准的检查程序(例如Pycharm内置的检查程序),您可能运气不佳。