Python,如果它的项目评估为False,如何实现一个列表子类,其值为False?

时间:2014-01-01 18:47:18

标签: python list boolean subclass

我已阅读overriding bool() for custom class并且它没有回答我的问题,“如果其项目评估为False,如何实现评估为False的列表子类”。具体而言,它没有解决:

  • 继承列表
  • 如果布尔上下文中的项目在布尔上下文中评估为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

1 个答案:

答案 0 :(得分:3)

容器的Python数据模型

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