代码之家  ›  专栏  ›  技术社区  ›  moshevi

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

  •  0
  • moshevi  · 技术社区  · 8 年前

    我有一个函数接收一个变量 x 检查它是“零”还是“空”。

    使用 PEP-484 类型提示语法,我将使用什么类型提示?

    我该如何检查它是否明确 boolable “通过提供自定义 __bool__ 或 __len__ 方法(因此 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"
    

    我不想只接受任何对象;所有对象都有一个真值,但对于没有 γ布尔 或 爱伦尼亚 总是这样 True .

    1 回复  |  直到 8 年前
        1
  •  1
  •   Michael0x2a    8 年前

    因此,首先,由于评论似乎对此有点困惑,我想我应该首先陈述我的假设。我假设你是想检查某个东西是0还是空的,或者是布尔型的。 静态地 --也就是说,可以使用PEP484类型对代码进行注释,并运行类似mypy的类型检查程序来确定变量是否为零。

    如果是 不 你要做的是,你要检查什么是零,空的,或是可调的。 运行时 (当实际运行代码时),您可以只使用isInstance检查——例如 assert x == 0 或 assert len(x) == 0 或 assert hasattr(x, '__bool__') or hasattr(x, '__len__') .


    如果你 是 尝试静态地检查某个值是否为零或空,不幸的是,对于PEP484类型,没有办法做到这一点。基本上,PEP484不允许您将“逻辑检查”与类型相关联——例如,您不能创建一个约束来强制某些函数只接受正整数。

    这在更复杂的类型系统中是可能的(参见从属类型系统、精化类型系统等),但实现此类类型系统非常复杂,因此极不可能在不久的将来修改PEP 484以支持类似的功能。

    也就是说,那里 是 一些计划至少为mypy添加对简单依赖类型的支持 字面量 . 例如,虽然我们可能无法轻易判断某个任意变量是否为零,但我们 可以 告诉你字面意思 0 是零。(此功能在尝试键入 open(...) 例如,函数——它根据第二个参数的值返回不同的类型)。

    有一些 related discussion here --也就是说,我不会屏息以待这项工作的实施。这是一个相对复杂的特性。

    目前,唯一真正的替代方法是使用运行时检查,或者只是重新构造代码,这样就不需要检查某个值是零还是空。


    但是,如果要通过检查是否存在 __bool__ 或 __len__ 方法,可以通过静态方式 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
    

    您需要安装 typing_extensions 首先使用PIP打包。协议还不是标准库的一部分,但预计将在不久的将来被标准化。我也不确定是否还有其他类型的checker超越了mypy支持协议。

    More documentation about protocols .