类型提示预期为布尔值且始终为空列表

Type hint expected boolean and always empty list

我有一个列表,我只需要检查它是否为空。

check = [] and True
print(check) # prints []
check = [1] and True
print(check) # prints True

我只想在 if 语句中使用 check 来检查变量的真实性,如下所示:

if check:
    print('Passed')

我应该这样输入提示吗?

from typing import Literal, Union
check: Union[Literal[True], Literal[[]]] = [] and True

我什至不知道如何注释一个始终为空的列表,但注释本身似乎很愚蠢,因为对于 reader,它只关心它的真实性。理想情况下,我只想要 check: bool = [] and True,但该语句并不总是 return 和 bool,所以它似乎不正确。

还有这个选项可以把它变成bool:

check: bool = not not [] and True

check: bool =  bool([]) and True

但这些似乎无缘无故地额外工作,因为我只需要真实性,而无论我得到的是空列表还是 False

那么,如果语句本身不是 return 布尔值,那么注释该语句仅在布尔上下文中解释的正确方法是什么?我只是将它转换为布尔值并使用 bool 进行注释,还是使用 Union[Literal[True], Literal[[]]] 之类的东西?附带说明一下,我不知道 Literal[[]] 是否是注释始终为空列表的正确方法(或者是否可能)。

我认为注释它的正确方法是使用 Union[List, bool] 但类型提示不会进行数据验证以检查列表是否为空 - 为此请看一下 PyDantic 在这个

from typing import List, Union


def check_list(my_list: Union[List, bool]):
    if my_list:
        print("got truth")
    else:
        print("got false")

核心 Python 允许动态输入。如果您知道只想在布尔上下文中使用 check,请使用 bool 对其进行注释并使用 and True.

check: bool
check = [] and True    # will contain []
...
check = [1] and True   # will contain True

当我在 PyCharm.

中测试它时,它没有给出任何警告

您还可以使用:

check: bool = [] and True    # will contain []
...
check: bool = [1] and True   # will contain True

也没有发出警告...

对我来说,这几乎感觉像是一个天生不好的类型检查候选者。在这种特定情况下,您实际上并不关心返回值的类型,只要您可以对其调用 bool 来测试其真实性即可。除非你正在使用 pandas/numpy 或类似的东西,否则很少有 python 对象你不能调用 bool — 它不需要存在__bool__ 方法或任何方法 — 因此您不能使用通常的鸭子打字解决方案,即使用 typing.Protocol。 (例如,参见 typing 模块中的 SupportsIntSupportsRound 类,它们都测试特定方法的存在。)

因此,我认为 typing.Any 的提示与像 typing.Union[list, bool] 这样更详尽的提示一样具有信息性和正确性。第二个中的额外信息对您的目的来说完全是多余的,在我看来。