我对Python集合的真值很感兴趣,比如{'a', 'b'}
,或者空集{{}
不同)。特别是,我想知道bool(my_set)
是否是False
当且仅当集合my_set
为空时。在
忽略原语(如数字)和用户定义的类型,https://docs.python.org/3/library/stdtypes.html#truth表示:
The following values are considered false:
- [...]
- any empty sequence, for example,
''
,()
,[]
.- any empty mapping, for example,
{}
.- [...]
All other values are considered true
根据https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range,集合不是序列(它是无序的,它的元素没有索引,等等):
There are three basic sequence types: lists, tuples, and range objects.
根据https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
There is currently only one standard mapping type, the dictionary.
因此,据我所知,set类型不是可以是False
的类型。但是,当我尝试时,bool(set())
的计算结果是False
。在
问题:
False
的集吗?在
在看过CPython的源代码之后,我想这是一个文档错误,但是,它可能与实现相关,因此在Python bug跟踪器上提出是一个很好的问题。在
具体来说,object.c定义项的真值如下:
我们可以清楚地看到,如果value is value不是布尔类型、None、sequence或映射类型,那么它将始终为true,这需要设置tp_as_sequence或tp_as_映射。在
幸运的是,查看setobject.c可以看出集合确实实现了tp_as_序列,这表明文档似乎不正确。在
^{pr2}$Dicts还将tp_实现为序列,因此看起来虽然它不是序列类型,但它类似于序列,这足够真实。在
在我看来,文档应该澄清这一点:映射类类型或类似序列的类型将是真实的,这取决于它们的长度。在
编辑正如user2357112正确指出的,}并不意味着类型是序列或映射。例如,dict实现
tp_as_sequence
和{tp_as_sequence
,list实现tp_as_mapping
。在^{} 的文档指出,调用此方法进行真值测试,如果未定义该方法,则对^{} 求值:
这适用于任何Python对象。如我们所见,
set
没有定义方法__bool__
:因此,真实性检验取决于
^{pr2}$__len__
:因此,只有空集(零长度)被认为是错误的。在
文档中truth value testing的部分在这方面不完整。在
这部分文档写得不好,或者更确切地说,维护不善。以下条款:
真正适用于所有类,无论是否用户定义,包括})。(在Python2中,
set
,dict
,甚至所有其他子句中列出的类型(所有这些子句都定义__bool__
或{None
是错误的,尽管没有__len__
或python2的__bool__
的等价物,但该异常是gone since Python 3.3。)我说维护得不好是因为这个部分至少从Python 1.4开始就几乎没有变化,也许更早。它的更新是为了添加
False
和删除单独的int/long类型,但不是为了类型/类的统一或集合的引入。在在编写quoted子句时,用户定义的类和内置类型的行为确实不同,我不认为内置类型在当时实际上没有}。在
__bool__
或{相关问题 更多 >
编程相关推荐