可以隐式检查 "zeroness" 或 "emptiness" 的变量类型
the type of a variable that can be implicitly checked for "zeroness" or "emptiness"
我有一个接收变量 x
并检查它是 "zeroness" 还是 "emptiness" 的函数。
使用 PEP-484 类型提示语法,我会使用什么类型提示?
我如何通过提供自定义 __bool__
或 __len__
方法来检查它是否明确为“boolable”(因此 bool(object)
[=35 的结果=]可能是False
),除了检查它是否真的实现了__bool__
或__len__
方法?
示例:
def my_func(x: "what goes here?"):
assert boolable(x) # what to do in this line?
if x:
"some logic"
else:
"some other logic"
我不想随便接受任何对象;所有对象都有一个真值,但对于没有 __bool__
或 __len__
的类型,它总是 True
.
所以首先,由于评论似乎对此有些困惑,我想我应该先陈述我的假设。我假设您正在尝试检查某些内容是否为 0 或空,或者是否可布尔 静态 —— 也就是说,您使用 PEP 484 类型和 [=61= 注释您的代码] 像 mypy 这样的类型检查器来确定变量是否为零。
如果这不是您想要做的,并且您正在尝试检查 [= 处的内容是否为零、空或可布尔值61=]time (实际上 运行ning 你的代码),你可以只使用 isinstance 检查——例如assert x == 0
或 assert len(x) == 0
或 assert hasattr(x, '__bool__') or hasattr(x, '__len__')
.
之类的东西
如果您正在 尝试静态检查某些内容是否为零或为空,不幸的是,无法使用 PEP 484 类型执行此操作。基本上,PEP 484 不允许您将 "logical checks" 与类型相关联——例如,您不能创建强制某些函数只接受正整数的约束。
这在更复杂的类型系统(参见依赖类型系统、细化类型系统等)中是可能的,但实现此类系统非常复杂,因此 PEP 484 极不可能被修改以支持诸如此类的功能这在不久的将来。
也就是说,有一些计划,至少 mypy 会添加对 文字 的简单依赖类型的支持。例如,虽然我们可能无法轻易判断某个任意变量是否为零,但我们 可以 判断文字 0
是否为零。 (此功能在尝试键入 open(...)
函数时特别有用,例如 - 根据第二个参数的值,它 returns 是不同的类型)。
有一些 related discussion here -- 那就是说,我不会屏住呼吸等待它的实施。这是一个相对复杂的功能。
目前,唯一真正的替代方法是回退到使用 运行时间检查,或者只是重构您的代码,这样您就不需要检查某些内容是否为零或为空。
但是,如果您想通过检查 __bool__
或 __len__
方法的存在来检查某些类型是否为 "boolable",您可以通过 using protocols:
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
您需要先使用 pip 安装 typing_extensions
包。协议还不是标准库的一部分,但有望在不久的将来实现标准化。我也不确定 mypy 之外的其他类型检查器是否支持协议。
我有一个接收变量 x
并检查它是 "zeroness" 还是 "emptiness" 的函数。
使用 PEP-484 类型提示语法,我会使用什么类型提示?
我如何通过提供自定义 __bool__
或 __len__
方法来检查它是否明确为“boolable”(因此 bool(object)
[=35 的结果=]可能是False
),除了检查它是否真的实现了__bool__
或__len__
方法?
示例:
def my_func(x: "what goes here?"):
assert boolable(x) # what to do in this line?
if x:
"some logic"
else:
"some other logic"
我不想随便接受任何对象;所有对象都有一个真值,但对于没有 __bool__
或 __len__
的类型,它总是 True
.
所以首先,由于评论似乎对此有些困惑,我想我应该先陈述我的假设。我假设您正在尝试检查某些内容是否为 0 或空,或者是否可布尔 静态 —— 也就是说,您使用 PEP 484 类型和 [=61= 注释您的代码] 像 mypy 这样的类型检查器来确定变量是否为零。
如果这不是您想要做的,并且您正在尝试检查 [= 处的内容是否为零、空或可布尔值61=]time (实际上 运行ning 你的代码),你可以只使用 isinstance 检查——例如assert x == 0
或 assert len(x) == 0
或 assert hasattr(x, '__bool__') or hasattr(x, '__len__')
.
如果您正在 尝试静态检查某些内容是否为零或为空,不幸的是,无法使用 PEP 484 类型执行此操作。基本上,PEP 484 不允许您将 "logical checks" 与类型相关联——例如,您不能创建强制某些函数只接受正整数的约束。
这在更复杂的类型系统(参见依赖类型系统、细化类型系统等)中是可能的,但实现此类系统非常复杂,因此 PEP 484 极不可能被修改以支持诸如此类的功能这在不久的将来。
也就是说,有一些计划,至少 mypy 会添加对 文字 的简单依赖类型的支持。例如,虽然我们可能无法轻易判断某个任意变量是否为零,但我们 可以 判断文字 0
是否为零。 (此功能在尝试键入 open(...)
函数时特别有用,例如 - 根据第二个参数的值,它 returns 是不同的类型)。
有一些 related discussion here -- 那就是说,我不会屏住呼吸等待它的实施。这是一个相对复杂的功能。
目前,唯一真正的替代方法是回退到使用 运行时间检查,或者只是重构您的代码,这样您就不需要检查某些内容是否为零或为空。
但是,如果您想通过检查 __bool__
或 __len__
方法的存在来检查某些类型是否为 "boolable",您可以通过 using protocols:
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
您需要先使用 pip 安装 typing_extensions
包。协议还不是标准库的一部分,但有望在不久的将来实现标准化。我也不确定 mypy 之外的其他类型检查器是否支持协议。