我已阅读overriding bool() for custom class并且它没有回答我的问题,“如果其项目评估为False,如何实现评估为False的列表子类”。具体而言,它没有解决:
可能有一个数据模型需要深层嵌套的列表列表,并且可能需要一个更简单的解决方案,而不是通过列表列表递归来确定它是否在布尔上下文中累积了一些评估为True的内容。
在Python中,空列表的评估结果为 False
>>> l = list()
>>> l
[]
>>> bool(l)
False
但是其中包含空列表(或其他0或空容器)的列表评估为 True
,因为包含列表的len是> 0
>>> l.append([])
>>> l
[[]]
>>> bool(l)
True
我可以对列表进行子类化,使其成为列表的实例,但如果它包含空列表或其他评估为空的内容,或者False
会返回False
吗?
即:
>>> l = MagicList((None, 0, {}, MagicList([0, False])))
>>> isinstance(l, list)
True
>>> bool(l)
False
答案 0 :(得分:3)
Python列表检查self.__len__()
,在布尔上下文中,我们学习from the Python 2 documentation:
...未定义
__nonzero__()
方法并且其__len__()
方法返回零的对象在布尔上下文中被视为false。
__nonzero__
documentation tells us:
被要求实施真值测试和内置操作 布尔();应该返回False或True,或者它们的整数等于0或 1.如果未定义此方法,则会调用
__len__()
...
因此,如果我们实现一个__nonzero__
方法,它将在评估为布尔值时快捷检查len,然后我们可以在其中评估布尔值:
class MagicList(list):
def __bool__(self): # Python 3 uses __bool__ instead of __nonzero__
return any(self)
__nonzero__=__bool__ # ensure Python 2 <-> 3 compatibility
并实例化,我们可以证明它是一个列表的实例,因为它是空的,所以评估为False
:
>>> l = MagicList()
>>> l
[]
>>> isinstance(l, list)
True
>>> bool(l)
False
如果我们使用一些空项扩展我们的列表,并继续返回 False
>>> l.extend([None, 0, {}])
>>> l
[None, 0, {}]
>>> len(l)
3
>>> bool(l)
False
如果附加一个评估为True的元素,它将返回 True
(这里我们追加另一个MagicList,其中0表示False,但也是一个len = 1的元组,用于评估为真)
>>> l.append(MagicList([0, (0,)]))
>>> l
[None, 0, {}, [0, (0,)]]
>>> bool(l)
True
这回答了寻找深层嵌套列表列表的动机,只要这些列表是在此创建的子类列表的实例。
最好使用内置数据类型,并在必要时以递归方式检查它们。这表明了一种可能性,不一定是最佳实践。
如果你这样做了,你必须明确检查len&gt; 0,如果这是您的兴趣点。
>>> len(l) > 0
True
>>> len(l)
4