为啥 len(None) 不返回 0?

Posted

技术标签:

【中文标题】为啥 len(None) 不返回 0?【英文标题】:Why doesn't len(None) return 0?为什么 len(None) 不返回 0? 【发布时间】:2015-07-27 06:00:01 【问题描述】:

None 在 Python 中是一个对象。

>>> isinstance(None, object)
True

因此它可以使用像 __str__() 这样的函数

>>> str(None)
'None'

但是为什么它对 __len__() 不做同样的事情呢?

>>> len(None)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    len(None)
TypeError: object of type 'NoneType' has no len()

这似乎是 Pythonic,就像 if list 是可以接受的一样,即使变量是 None 而不仅仅是一个空列表。

是否存在使len(None) 的使用更成问题的情况?

【问题讨论】:

因为None 没有__len__;不是Sized @jonrsharpe 但它可能只是添加了一个无论如何都返回 0 的函数。 可以,但没有多大意义。为什么一个对象有一个长度,除非它是一个对象的集合? 如果您有可能获得Nonelist 的情况,您应该先测试if what_i_think_is_a_list is not None:,然后再将其视为列表。所有内置类型都有真实性,但有很多操作在 None 上毫无意义(你也不能迭代它)。为None 实现len 只会隐藏应捕获的错误。 None 没有长度,原因与整数和浮点数没有长度相同。 这不是一个集合。它不能变长或变短。 【参考方案1】:

如果您有一个可能返回None 的项目,您可以使用len(None or ''),它将返回return 0 或第一个项目的长度(如果它是not None)。

【讨论】:

【参考方案2】:

你提到你想要这个:

因为当函数返回 None 而不是列表时,它经常作为错误出现

大概,你有这样的代码:

list_probably = some_function()
for index in range(len(list_probably)):
    ...

并且正在获得:

TypeError: object of type 'NoneType' has no len()

注意以下几点:

len 用于确定集合的长度(例如listdictstr - 这些是Sized 对象)。 不是用于将任意对象转换为整数 - 例如,它也不适用于 intbool; 如果None 是可能的,您应该明确地测试if list_probably is not None。使用例如if list_probably 会将 None 和空列表 [] 视为相同,这可能不是正确的行为;和 通常有更好的方法来处理range(len(...)) 的列表,例如for item in list_probably,使用zip

None 实现len 只会隐藏错误,其中None 被错误地处理,就像其他一些对象一样 - 每个the Zen of Python (import this):

错误不应该默默地过去。

同样for item in None 会失败,但这并不意味着实现None.__iter__ 是一个好主意!错误是一件好事 - 它们可以帮助您快速找到程序中的问题。

【讨论】:

【参考方案3】:

len 仅对对象集合有意义 - None 不是集合。

【讨论】:

说它总是返回 0 是否比 None 的真实性(或虚假性)更有意义? @SuperBiasedMan 是的,它没有多大意义。问问自己,红色的长度是 0 吗? @SuperBiasedMan 是的!整数也没有长度,但有真实性 - 请参阅docs.python.org/2/library/stdtypes.html#truth-value-testing。另请注意,您通常应该通过 identity 而不是 truthiness 来测试 None @jonrsharpe 这一点特别好。我想我在考虑 len() 只是返回一个表示变量的 int 值,而不是显式地作为集合的计数。 (我也指的是用真实性测试一个列表,当你有 None 而不是列表时它会处理这种情况)

以上是关于为啥 len(None) 不返回 0?的主要内容,如果未能解决你的问题,请参考以下文章

如果数字不是偶数,为啥这个函数会返回“None”?如何在不使用其他条件的情况下使其返回“False”?

为啥返回一个负的errno? (例如,返回 -EIO)

我的python为啥dict没有isnull方法?

C++里面,为啥重载前++时不返回引用就不能连用?

python调用mysql中的自定义变量,为啥返回的值都是None

为啥我的递归函数返回 None?