Python PEP 484:类型提示的独占类型
我可以指定独占类型吗?大概是这样的:Python PEP 484:类型提示的独占类型,python,python-3.5,type-hinting,Python,Python 3.5,Type Hinting,我可以指定独占类型吗?大概是这样的: def foo(bar: Not[str]) -> None: assert not isinstance(bar, str) print(type(bar)) PEP 484不包括指定“黑名单”类型的内置方式 做那种事情通常是没有意义的——我能想到你为什么想做这样的事情的唯一原因是如果你想以某种方式区分str和Iterable[str]或Sequence[str]。如果是这样的话,不幸的是,PEP 484--str,不管是好是坏,都
def foo(bar: Not[str]) -> None:
assert not isinstance(bar, str)
print(type(bar))
PEP 484不包括指定“黑名单”类型的内置方式 做那种事情通常是没有意义的——我能想到你为什么想做这样的事情的唯一原因是如果你想以某种方式区分
str
和Iterable[str]
或Sequence[str]
。如果是这样的话,不幸的是,PEP 484--str,不管是好是坏,都是这两种类型的合法子类
在这种情况下,您最好修改您的类型签名,以区分str
和List[str]
这两个合法可区分的类。不理想,但总比没有好
也就是说,如果你真的想做这样的事情,假设你正在使用mypy,并且不介意使用肮脏的黑客,那么这是有可能的 一个技巧是基本上修改
foo
函数,使其总是返回一些东西,并滥用重载
和非严格可选模式的语义,如下所示:
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
标记,mypy将用标记最后一行,“foo”不返回值
错误。然后您需要记住,发生此错误消息是因为您传入了一个字符串参数。您还需要记住始终将foo
函数的输出指定给一个值
(如果启用了strict optional,mypy会抱怨两个重载具有不兼容的签名。)
我们在这里主要做的是:
None
是每种类型的合法值(因此重载是合法的)你可以尝试的第二个技巧是编写一个mypy插件来捕获你的特定案例的实例。在撰写本文时,mypy插件系统是一个没有文档记录的、暂时的、很容易更改的特性,但是如果您真的想这样做,这可能是需要调查的
如果您特别想要区分
str
和Sequence[str]
或Iterable[str]
(或类似的东西),您可以尝试的其他方法是:
str
的类定义/存根,使其不会继承Sequence[str]
或Iterable[str]
(或添加幻影类型或其他内容)--custom typeshed dir
和--custom typing
命令行参数使mypy使用自定义类型定义当然,如果您使用的是其他与PEP 484兼容的检查器(例如Pycharm的内置检查器),您可能会运气不佳。PEP 484没有内置指定“黑名单”类型的方法 做那种事情通常是没有意义的——我能想到你为什么想做这样的事情的唯一原因是如果你想以某种方式区分
str
和Iterable[str]
或Sequence[str]
。如果是这样的话,不幸的是,PEP 484--str,不管是好是坏,都是这两种类型的合法子类
在这种情况下,您最好修改您的类型签名,以区分str
和List[str]
这两个合法可区分的类。不理想,但总比没有好
也就是说,如果你真的想做这样的事情,假设你正在使用mypy,并且不介意使用肮脏的黑客,那么这是有可能的 一个技巧是基本上修改
foo
函数,使其总是返回一些东西,并滥用重载
和非严格可选模式的语义,如下所示:
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
标记,mypy将用标记最后一行,“foo”不返回值
错误。然后您需要记住,发生此错误消息是因为您传入了一个字符串参数。您还需要记住始终将foo
函数的输出指定给一个值
(如果启用了strict optional,mypy会抱怨两个重载具有不兼容的签名。)
我们在这里主要做的是:
None
是每种类型的合法值(因此重载是合法的)你可以尝试的第二个技巧是编写一个mypy插件来捕获你的特定案例的实例。在撰写本文时,mypy插件系统是一个没有文档记录的、暂时的、很容易更改的特性,但是如果您真的想这样做,这可能是需要调查的
如果您特别想要区分
str
和Sequence[str]
或Iterable[str]
(或类似的东西),您可以尝试的其他方法是:
str
的类定义/存根,使其不继承任何一个