首先,由于评论似乎对此有点困惑,我想我应该首先陈述我的假设。我假设您正在尝试检查某些内容是否为 0 或空,或者是否为布尔值静态地-- 也就是说,您使用 PEP 484 类型注释代码并运行 mypy 等类型检查器来确定变量是否为零。
如果那是not你正在尝试做的事情,并且你正在尝试检查某些内容是否为零或为空或可布尔runtime(当实际运行你的代码时),你可以只使用 isinstance 检查 - 例如像这样的东西assert x == 0
or assert len(x) == 0
or assert hasattr(x, '__bool__') or hasattr(x, '__len__')
.
If you are尝试静态检查某些内容是否为零或空,不幸的是,无法使用 PEP 484 类型执行此操作。基本上,PEP 484 不允许您将“逻辑检查”与类型相关联——例如,您不能创建强制某些函数仅接受正整数的约束。
这在更复杂的类型系统中是可能的(参见依赖类型系统、细化类型系统等),但实现此类类型系统非常复杂,因此在不久的将来修改 PEP 484 以支持此类功能的可能性极小。
也就是说,有are至少 mypy 的一些计划添加对简单依赖类型的支持literals。例如,虽然我们可能无法轻易判断某个任意变量是否为零,但我们can告诉字面意思0
是零。 (当尝试输入以下内容时,此功能特别有用open(...)
例如,函数——它根据第二个参数的值返回不同的类型)。
有一些相关讨论在这里 https://github.com/python/mypy/issues/3062——也就是说,我不会屏住呼吸等待这一实施。这是一个相对复杂的功能。
目前,唯一真正的替代方案是退回到使用运行时检查或仅重组代码,这样您就不需要检查某些内容是否为零或为空。
但是,如果您想通过检查是否存在来检查某种类型是否“可布尔”__bool__
or __len__
方法,您可以通过静态方式执行此操作使用协议 https://www.python.org/dev/peps/pep-0544/:
from typing import Union
from typing_extensions import Protocol
class HasBool(Protocol):
def __bool__(self) -> bool: ...
class HasLen(Protocol):
def __len__(self) -> int: ...
Boolable = Union[HasBool, HasLen]
def accepts_boolable(x: Boolable) -> None: pass
accepts_boolable(3)
accepts_boolable("asdf")
class NotBoolable: pass
accepts_boolable(NotBoolable()) # Mypy reports an error
您需要安装typing_extensions
首先使用 pip 进行打包。协议尚未成为标准库的一部分,但预计将在不久的将来实现标准化。我也不确定 mypy 之外的其他类型检查器是否支持协议。
有关协议的更多文档 https://mypy.readthedocs.io/en/latest/protocols.html.