可以隐式检查“零”或“空”的变量类型

2024-04-20 14:06:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个函数,它接收一个变量x,并检查它是“零”还是“空”。你知道吗

使用PEP-484类型提示语法,我将使用什么类型的提示?你知道吗

除了检查它是否实际实现了__bool____len__方法之外,我如何通过提供一个定制的__bool____len__方法来检查它是否显式地是boolable(因此bool(object)的结果可能是False)?你知道吗

示例:

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。你知道吗


Tags: 对象方法函数false示例类型lenobject
1条回答
网友
1楼 · 发布于 2024-04-20 14:06:04

因此,首先,由于评论似乎对此有点困惑,我想我应该首先陈述我的假设。我假设您正在尝试检查某个内容是0还是空的,或者是静态可booable也就是说,您使用pep484类型对代码进行注释,并运行mypy之类的类型检查器来确定变量是否为零。你知道吗

如果这不是你想做的,并且你想在运行时检查某个东西是零还是空或者是可booable的(当实际运行你的代码时),你可以使用isinstance检查,比如assert x == 0或者assert len(x) == 0或者assert hasattr(x, '__bool__') or hasattr(x, '__len__')。你知道吗


如果您试图静态地检查某个内容是零还是空,那么不幸的是,pep484类型无法做到这一点。基本上,pep484不允许将“逻辑检查”与不能创建约束的类型相关联,例如,强制某些函数只接受正整数。你知道吗

这在更复杂的类型系统中是可能的(参见依赖类型系统、精化类型系统等),但是实现这样的类型系统非常复杂,因此在不久的将来修改pep484以支持这样的特性是极不可能的。你知道吗

也就是说,至少有一些mypy计划为文本添加对简单依赖类型的支持。例如,虽然我们可能无法很容易地判断某个任意变量是否为零,但我们可以判断文字0是零。(此功能在尝试键入open(...)函数时特别有用,例如,它根据第二个参数的值返回不同的类型)。你知道吗

有些related discussion here说,我不会屏住呼吸等待这个实现。这是一个相对复杂的特征。你知道吗

目前,唯一真正的替代方法是退回到使用运行时检查,或者只是重新构造代码,这样就不需要检查是零还是空。你知道吗


但是,如果要通过检查__bool____len__方法的存在来检查某个类型是否“可booable”,则可以通过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支持协议尚未。你知道吗

More documentation about protocols。你知道吗

相关问题 更多 >