为什么Python中没有++和——运算符?
当前回答
这并不是因为它没有意义;将“x++”定义为“x+ = 1,求值到x的前一个绑定”非常有意义。
如果你想知道最初的原因,你必须在旧的Python邮件列表中寻找,或者询问当时在那里的人(例如。Guido),但事后很容易就能证明:
简单的递增和递减不需要像其他语言那样多。你不会写这样的for(int i = 0;I < 10;i)在Python中经常使用;相反,你可以把I放在(0,10)范围内。
由于不经常需要它,所以没有理由给它自己的特殊语法;当您确实需要增加时,+=通常就可以了。
It's not a decision of whether it makes sense, or whether it can be done--it does, and it can. It's a question of whether the benefit is worth adding to the core syntax of the language. Remember, this is four operators--postinc, postdec, preinc, predec, and each of these would need to have its own class overloads; they all need to be specified, and tested; it would add opcodes to the language (implying a larger, and therefore slower, VM engine); every class that supports a logical increment would need to implement them (on top of += and -=).
这些都是+=和-=的冗余,所以会变成净损失。
其他回答
这并不是因为它没有意义;将“x++”定义为“x+ = 1,求值到x的前一个绑定”非常有意义。
如果你想知道最初的原因,你必须在旧的Python邮件列表中寻找,或者询问当时在那里的人(例如。Guido),但事后很容易就能证明:
简单的递增和递减不需要像其他语言那样多。你不会写这样的for(int i = 0;I < 10;i)在Python中经常使用;相反,你可以把I放在(0,10)范围内。
由于不经常需要它,所以没有理由给它自己的特殊语法;当您确实需要增加时,+=通常就可以了。
It's not a decision of whether it makes sense, or whether it can be done--it does, and it can. It's a question of whether the benefit is worth adding to the core syntax of the language. Remember, this is four operators--postinc, postdec, preinc, predec, and each of these would need to have its own class overloads; they all need to be specified, and tested; it would add opcodes to the language (implying a larger, and therefore slower, VM engine); every class that supports a logical increment would need to implement them (on top of += and -=).
这些都是+=和-=的冗余,所以会变成净损失。
我对python为什么没有++操作符的理解如下:当你用python写这个时,a=b=c=1,你会得到三个变量(标签)指向同一个对象(值为1)。你可以使用id函数来验证这一点,它将返回一个对象内存地址:
In [19]: id(a)
Out[19]: 34019256
In [20]: id(b)
Out[20]: 34019256
In [21]: id(c)
Out[21]: 34019256
所有三个变量(标签)都指向同一个对象。现在增加变量之一,看看它是如何影响内存地址的:
In [22] a = a + 1
In [23]: id(a)
Out[23]: 34019232
In [24]: id(b)
Out[24]: 34019256
In [25]: id(c)
Out[25]: 34019256
你可以看到变量a现在指向另一个对象,变量b和c。因为你已经使用了a = a + 1,这是明确的。换句话说,你将完全另一个对象赋值给标签a。想象一下,你可以写一个++,这将表明你没有给变量赋值一个新对象,而是给旧对象赋值。所有这些东西都是为了尽量减少混淆。为了更好地理解python变量是如何工作的:
在Python中,为什么函数可以修改调用者感知到的一些参数,而不能修改其他参数?
Python是按值调用还是按引用调用?既不。
Python是按值传递还是按引用传递?
Python是按引用传递还是按值传递?
如何通过引用传递变量?
理解Python变量和内存管理
在python中模拟值传递行为
Python函数通过引用调用
像Pythonista一样编写代码:地道的Python
除了这里的其他优秀答案之外,++和——也因未定义的行为而臭名昭著。例如,这段代码中发生了什么?
foo[bar] = bar++;
它看起来很无辜,但它是错误的C(和c++),因为您不知道第一个栏是否会增加。一个编译器可能会以一种方式执行,另一个可能会以另一种方式执行,而第三个编译器可能会让恶魔从你的鼻子里飞出来。所有这些都完全符合C和c++标准。
(编辑:c++ 17改变了给定代码的行为,这样它就被定义了;它将等价于foo[bar+1] = bar;+ +酒吧;——尽管如此,这可能不是程序员所期望的。)
在C和c++中,未定义行为被视为不可避免的邪恶,但在Python中,它只是邪恶,并尽可能避免。
其他答案描述了为什么迭代器不需要它,但有时它在赋值以inline增加变量时很有用,你可以使用元组和多次赋值达到相同的效果:
B = ++a变成:
a,b = (a+1,)*2
b = a++变成:
a,b = a+1, a
Python 3.8引入了赋值:=操作符,允许我们用
foo(a:=a+1)
Foo (a++)仍然是难以捉摸的。
我最初写的这个答案是一个来自计算机民间传说的神话:丹尼斯·里奇(Dennis Ritchie)在2012年7月给ACM通讯编辑的信中指出,它被揭穿为“历史上不可能的”doi:10.1145/2209249.2209251
C加/减操作符是在C编译器还不是很聪明的时候发明的,作者希望能够指定应该使用机器语言操作符的直接意图,这为编译器节省了一些周期
load memory
load 1
add
store memory
而不是
inc memory
PDP-11甚至支持“自动递增”和“自动递增延迟”指令,分别对应于*++p和*p++。如果非常好奇,请参阅手册5.3节。
由于编译器足够聪明,可以处理C语法中内置的高级优化技巧,所以它们现在只是语法上的便利。
Python没有向汇编器传递意图的技巧,因为它不使用这些技巧。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录