为啥 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 的函数。
可以,但没有多大意义。为什么一个对象有一个长度,除非它是一个对象的集合?
如果您有可能获得None
或list
的情况,您应该先测试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
用于确定集合的长度(例如list
、dict
或str
- 这些是Sized
对象)。 不是用于将任意对象转换为整数 - 例如,它也不适用于 int
或 bool
;
如果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”?