Python 中对可变对象进行原地操作的函数——为什么返回值不是self?

本文解析了Python代码中a.append(4)为何返回None,以及list.sort()不返回排序列表的原因。重点在于Python的设计哲学,即就地操作以提高性能,但可能导致误用。通过理解返回None的机制,提升代码可读性和避免潜在错误。
摘要由CSDN通过智能技术生成

错误发生

下面的代码对 list 对象使用了 append()方法添加一个元素,并将其存入一个元组,以供后续操作。但在代码后续运行的时候发生了错误,报错信息是正在对 None 进行 append()操作。
代码大致如下:

>>> a = [1, 2, 3]
>>> b = ("other", a.append(4))
>>> b[1].append(9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'append'

原因

append()方法的返回值为 None,而不是 list 对象本身。

>>> a = [1, 2, 3]
>>> b = ("other", a.append(4))
>>> print(a)
[1, 2, 3, 4]
>>> print(b)
('other', None)
>>> c = a.append(5)
>>> print(c)
None
>>> type(c)
<class 'NoneType'>

那为什么这个方法返回的是 None ,而不是列表本身呢?我对此感到十分的困惑。

官方文档中的解释

其实这个问题和为什么 list.sort() 返回 None 非常相似,我们可以通过阅读官方的设计和历史文档了解到其中的原因。

In situations where performance matters, making a copy of the list just to sort it would be wasteful. Therefore, list.sort() sorts the list in place. In order to remind you of that fact, it does not return the sorted list. This way, you won’t be fooled into accidentally overwriting a list when you need a sorted copy but also need to keep the unsorted version around.

Why doesn’t list.sort() return the sorted list?

大致说的是 list.sort()是对列表进行原地排序。这么设计的目的是,如果你也想保留并未排序的原来列表,这样可以防止你意外覆盖原来的列表。

Python 的设计原则

事实上,Python 的一般设计原则是,就地改变对象的函数(不创建新的对象)一律都返回 None 。Python 的设计者 Guido van Rossum 在下面的邮件中阐述了自己对此的观点。

I find the chaining form a threat to readability; it requires that the
reader must be intimately familiar with each of the methods. The
second form makes it clear that each of these calls acts on the same
object, and so even if you don’t know the class and its methods very
well, you can understand that the second and third call are applied to
x (and that all calls are made for their side-effects), and not to
something else.

[Python-Dev] sort() return value

大致意思是说 Method Chaining 降低了代码的可读性,并有造成错误的潜在威胁。

总结

在 Python 中就地改变对象的函数的返回值是 None 。除非清晰地了解函数的副作用,否做不要在代码中使用 Method Chaining。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值