Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?

2020-07-15 20:15:52 +08:00
 chinesehuazhou

分享一篇文章:

在 C/C++/Java 等等语言中,整型变量的自增或自减操作是标配,它们又可分为前缀操作(++i 和 --i )与后缀操作( i++ 和 i--),彼此存在着一些细微差别,各有不同的用途。

这些语言的使用者在接触 Python 时,可能会疑惑为什么它不提供 ++ 或 -- 的操作呢?在我前不久发的《Python 的十万个为什么?》里,就有不少同学在调查问卷中表示了对此话题感兴趣。

Python 中虽然可能出现 ++i 这种前缀形式的写法,但是它并没有“++”自增操作符,此处只是两个“+”(正数符号)的叠加而已,至于后缀形式的“++”,则完全不支持( SyntaxError: invalid syntax )。

本期“Python 为什么 ”栏目,我们将会从两个主要的角度来回答:Python 为什么不支持 i++ 自增语法? ( PS:此处自增指代“自增和自减”,下同)

首先,Python 当然可以实现自增效果,即写成i += 1 或者 i = i + 1 ,这在其它语言中也是通用的。

虽然 Python 在底层用了不同的魔术方法(__add__()__iadd__() )来完成计算,但表面上的效果完全相同。

所以,我们的问题可以转化成:为什么上面的两种写法会胜过 i++,成为 Python 的最终选择呢?

1 、Python 的整数是不可变类型

当我们定义i = 1000 时,不同语言会作出不同的处理:

所以当我们令 i “自增”时( i = i + 1 ),它们的处理是不同的:

打一个不太恰当的比方:C 中的 i 就像一个宿主,数字 1000 寄生在它上面;而 Python 中的 1000 像个宿主,名称 i 寄生在它上面。C 中的 i 与 Python 中的 1000,它们则寄生在底层的内存空间上……

还可以这样理解:C 中的变量 i 是一等公民,数字 1000 是它的一个可变的属性; Python 中的数字 1000 是一等公民,名称 i 是它的一个可变的属性。

有了以上的铺垫,我们再来看看 i++,不难发现:

Python 若支持 i++,其操作过程要比 C 的 i++ 复杂,而且其含义也不再是“令数字增加 1”(自增),而是“创建一个新的数字”(新增), 这样的话,“自增操作符”( increment operator )就名不副实了。

Python 在理论上可以实现 i++ 操作,但它就必须重新定义“自增操作符”,还会令有其它语言经验的人产生误解,不如就让大家直接写成i += 1 或者 i = i + 1 好了。

2 、Python 有可迭代对象

C/C++ 等语言设计出 i++,最主要的目的是为了方便使用三段式的 for 结构:

for(int i = 0; i < 100; i++){
    // 执行 xxx
}

这种程序关心的是数字本身的自增过程,数字做加法与程序体的执行相关联。

Python 中没有这种 for 结构的写法,它提供了更为优雅的方式:

for i in range(100):
    # 执行 xxx

my_list = ["你好", "我是 Python 猫", "欢迎关注"]
for info in my_list:
    print(info)

这里体现了不同的思维方式,它关心的是在一个数值范围内的迭代遍历,并不关心也不需要人为对数字做加法。

Python 中的可迭代对象 /迭代器 /生成器提供了非常良好的迭代 /遍历用法,能够做到对 i++ 的完全替代。

例如,上例中实现了对列表内值的遍历,Python 还可以用 enumerate() 实现对下标与具体值的同时遍历:

my_list = ["你好", "我是 Python 猫", "欢迎关注"]
for i, info in enumerate(my_list):
    print(i, info)

# 打印结果:
0 你好
1 我是 Python 猫
2 欢迎关注

再例如对于字典的遍历,Python 提供了 keys()、values()、items() 等遍历方法,非常好用:

my_dict = {'a': '1', 'b': '2', 'c': '3'}
for key in my_dict.keys():
    print(key)

for key, value in my_dict.items():
    print(key, value)

有了这样的利器,哪里还有 i++ 的用武之地呢?

不仅如此,Python 中基本上很少使用i += 1 或者 i = i + 1 ,由于存在着随处可见的可迭代对象,开发者们很容易实现对一个数值区间的操作,也就很少有对于某个数值作累加的诉求了。

所以,回到我们开头的问题,其实这两种“自增”写法并没有胜出 i++ 多少,只因为它们是通用型操作,又不需要引入新的操作符,所以 Python 才延续了一种基础性的支持。真正的赢家其实是各种各样的可迭代对象!

稍微小结下:Python 不支持自增操作符,一方面是因为它的整数是不可变类型的一等公民,自增操作(++)若要支持,则会带来歧义;另一方面主要因为它有更合适的实现,即可迭代对象,对遍历操作有很好的支持。

如果你觉得本文分析得不错,那你应该会喜欢这些文章:

1 、Python 为什么使用缩进来划分代码块?

2 、Python 的缩进是不是反人类的设计?

3 、Python 为什么不用分号作语句终止符?

4 、Python 为什么没有 main 函数?为什么我不推荐写 main 函数?

5 、Python 为什么推荐蛇形命名法?

6 、Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符

7 、Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?

写在最后:本文属于“Python 为什么”系列( Python 猫出品),该系列主要关注 Python 的语法、设计和发展等话题,以一个个“为什么”式的问题为切入点,试着展现 Python 的迷人魅力。

1170 次点击
所在节点    Python
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/690363

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX