为啥 list.append 在布尔上下文中评估为 false? [复制]

Posted

技术标签:

【中文标题】为啥 list.append 在布尔上下文中评估为 false? [复制]【英文标题】:Why does list.append evaluate to false in a boolean context? [duplicate]为什么 list.append 在布尔上下文中评估为 false? [复制] 【发布时间】:2010-12-13 13:05:00 【问题描述】:

list.append 评估为假是否有原因?还是只是成功时返回 0 的 C 约定起作用?

>>> u = []
>>> not u.append(6)
True

【问题讨论】:

一种可能更好的表达方式:为什么python不使用Builder模式..所以我们可以这样做u.append(6).append(7). ..这很烦人。 @javadba 为什么不直接做u.extend((6, 7)) @Stefan append()extend() 效果不同,不可互换 @javadba 有什么区别?我的扩展与您的两个附加具有相同的效果。 extend() 如果元素是列表,则保留单个列表,而 append() 将是列表列表。在上述情况下,它们不是,所以这是一个特殊情况,在 extend() 和 append() 之间最终结果相同。 【参考方案1】:

大多数就地改变容器的 Python 方法返回 None——Command-query separation 原则的应用。 (Python 在事情上总是相当务实,所以一些 mutators 在获取它时确实会返回一个可用的值,否则会很昂贵或一团糟——pop 方法是这种实用主义的一个很好的例子——但这些绝对是例外,不是规则,也没有理由让append 例外)。

【讨论】:

【参考方案2】:

None 的计算结果为 False,而在 python 中,一个不返回任何内容的函数被假定为返回了 None

如果你输入:

>> print u.append(6)
None

Tadaaam :)

【讨论】:

更新列表的修改器(如追加、扩展、排序等)不返回值。 None 不会评估False @SwiftsNamesake 试试bool(None) @Chris_Rands None 不是布尔值,这就是为什么需要bool 函数来转换它(由not 隐式完成)。是的,我知道这是一个狡辩,但它是 True @SwiftsNamesake 我发现 evaluates 比 Python 自己的语义更清晰,help(bool) 说“bool(x): Returns True when the argument x is true”。但是x是真的好像和x is True太相似了,当然意思完全不同【参考方案3】:

因为.append 方法返回None,因此not None 的计算结果为True。 Python on error 通常会引发错误:

>>> a = ()
>>> a.append(5)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    a.append(5)
AttributeError: 'tuple' object has no attribute 'append'

【讨论】:

【参考方案4】:

它就地修改列表,并返回NoneNone 计算结果为假。

【讨论】:

【参考方案5】:

其实是返回None

>>> print u.append(6) None >>> print not None True >>>

【讨论】:

【参考方案6】:

方法append就地修改列表,返回值None

在您的情况下,您正在动态创建一个数组 - [6],然后将其丢弃。变量 b 以 None 的返回值结束。

为什么? 这符合 Bertrand Meyer 设计的Command–query separation 原则。 它指出,每个方法都应该是执行操作的命令,或者是向调用者返回数据的查询,但不能同时是两者。 在您的示例中:

u.append(6)

append修改了[]的状态,所以返回符合原则的值并不是最佳实践。

从理论上讲,这建立了一个健全的衡量标准,由此人们可以推断程序的状态,而无需同时修改该状态。

CQS 非常适合 python 等面向对象的方法。

【讨论】:

这也破坏了builder() 模式。这是 python 难以使用的众多原因之一。【参考方案7】:

list.append 函数返回None。它只是将值添加到您从中调用方法的列表中。

这里有一些东西会让事情变得更清楚:

>>> u = []
>>> not u
False
>>> print(u.append(6)) # u.append(6) == None
None    
>>> not u.append(6) # not None == True
True

【讨论】:

以上是关于为啥 list.append 在布尔上下文中评估为 false? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 append() 在 Python 中总是返回 None? [复制]

为啥 append() 在 Python 中总是返回 None? [复制]

为啥在 if 语句中使用双感叹号?

为啥没有在动态 SQL 中评估数学条件?

为啥 + 运算符不更改列表而 .append() 呢?

为啥这个 if 语句以非布尔值成功?