Python 中自增和自减运算符的行为
如何使用预自增/自减运算符(++
、--
),就像在 C++ 中一样?
为什么++count
运行,但不改变变量的值?
How do I use pre-increment/decrement operators (++
, --
), just like in C++?
Why does ++count
run, but not change the value of the variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
++
不是运算符。它是两个+
运算符。+
运算符是identity 运算符,它不执行任何操作。 (澄清:+
和-
一元运算符仅适用于数字,但我认为您不会期望假设的++
运算符处理字符串。)解析为
翻译为
你必须使用稍长的
+=
运算符来完成你想做的事情:我怀疑
++
和-- 运算符。我不知道 Guido van Rossum 为该决定给出的确切论点,但我可以想象一些论点:
++count
是不明确的,因为它可能是+
、+
、count
(两个一元 < code>+ 运算符)就像++
、count
(一个一元++
运算符)一样简单。这不是一个重大的语法歧义,但它确实存在。++
只不过是+= 1
的同义词。这是一种简写形式,因为 C 编译器很愚蠢,不知道如何将a += 1
优化为大多数计算机都有的inc
指令。在优化编译器和字节码解释语言的今天,向语言添加运算符以允许程序员优化其代码通常是不受欢迎的,尤其是在像 Python 这样被设计为一致和可读的语言中。++
运算符的语言中一个常见的新手错误是混淆了前后递增/递减运算符之间的差异(优先级和返回值),而 Python 喜欢消除语言“陷阱”-s。 优先级问题 C 中的前置/后置增量 非常复杂,而且非常容易搞乱。++
is not an operator. It is two+
operators. The+
operator is the identity operator, which does nothing. (Clarification: the+
and-
unary operators only work on numbers, but I presume that you wouldn't expect a hypothetical++
operator to work on strings.)Parses as
Which translates to
You have to use the slightly longer
+=
operator to do what you want to do:I suspect the
++
and--
operators were left out for consistency and simplicity. I don't know the exact argument Guido van Rossum gave for the decision, but I can imagine a few arguments:++count
is ambiguous, as it could be+
,+
,count
(two unary+
operators) just as easily as it could be++
,count
(one unary++
operator). It's not a significant syntactic ambiguity, but it does exist.++
is nothing more than a synonym for+= 1
. It was a shorthand invented because C compilers were stupid and didn't know how to optimizea += 1
into theinc
instruction most computers have. In this day of optimizing compilers and bytecode interpreted languages, adding operators to a language to allow programmers to optimize their code is usually frowned upon, especially in a language like Python that is designed to be consistent and readable.++
operators is mixing up the differences (both in precedence and in return value) between the pre- and post-increment/decrement operators, and Python likes to eliminate language "gotcha"-s. The precedence issues of pre-/post-increment in C are pretty hairy, and incredibly easy to mess up.Python 没有前置和后置增量运算符。
在 Python 中,整数是不可变的。那就是你无法改变它们。这是因为整数对象可以用多个名称使用。试试这个:
上面的 a 和 b 实际上是同一个对象。如果你增加 a,你也会增加 b。那不是你想要的。所以你必须重新分配。像这样:
许多使用 python 的 C 程序员想要一个递增运算符,但该运算符看起来像是递增了对象,而实际上是重新分配了对象。因此,添加了
-=
和+=
运算符,比b = b + 1
更短,同时比b = b + 1
更清晰、更灵活b++
,所以大多数人都会用以下方式递增:这会将
b
重新分配给b+1
。这不是一个递增运算符,因为它不会递增b
,而是重新分配它。简而言之:Python 在这里的行为有所不同,因为它不是 C,也不是机器代码的低级包装器,而是一种高级动态语言,其中增量没有意义,也不像 C 那样必要,例如,每次有循环时都使用它们。
Python does not have pre and post increment operators.
In Python, integers are immutable. That is you can't change them. This is because the integer objects can be used under several names. Try this:
a and b above are actually the same object. If you incremented a, you would also increment b. That's not what you want. So you have to reassign. Like this:
Many C programmers who used python wanted an increment operator, but that operator would look like it incremented the object, while it actually reassigns it. Therefore the
-=
and+=
operators where added, to be shorter than theb = b + 1
, while being clearer and more flexible thanb++
, so most people will increment with:Which will reassign
b
tob+1
. That is not an increment operator, because it does not incrementb
, it reassigns it.In short: Python behaves differently here, because it is not C, and is not a low level wrapper around machine code, but a high-level dynamic language, where increments don't make sense, and also are not as necessary as in C, where you use them every time you have a loop, for example.
虽然其他答案就其显示的仅
+
通常的作用而言是正确的(即,如果数字是一个,则保持原样),但就其不完整而言,它们是不完整的不解释发生了什么。确切地说,
+x
计算结果为x.__pos__()
,++x
计算结果为x.__pos__().__pos__( )
。我可以想象一个非常奇怪的类结构(孩子们,不要在家里这样做!),如下所示:
While the others answers are correct in so far as they show what a mere
+
usually does (namely, leave the number as it is, if it is one), they are incomplete in so far as they don't explain what happens.To be exact,
+x
evaluates tox.__pos__()
and++x
tox.__pos__().__pos__()
.I could imagine a VERY weird class structure (Children, don't do this at home!) like this:
在 python 3.8+ 中你可以这样做:
你可以用它做很多思考。
或者,如果你想用更复杂的语法编写一些东西(目标不是优化):
即使 'a' 不存在并且没有错误,它也会返回 0,然后将其设置为 1
In python 3.8+ you can do :
You can do a lot of thinks with this.
Or if you want write somthing with more sophisticated syntaxe (the goal is not optimization):
It will return 0 even if 'a' doesn't exist without errors, and then will set it to 1
TL;DR
Python 没有一元递增/递减运算符 (
--
/++
)。相反,要增加一个值,请使用更多细节和陷阱,
但这里要小心。如果你来自 C,即使这在 python 中也是不同的。 Python 没有 C 那样的“变量”,相反,Python 使用名称和对象,并且在 Python 中,int 是不可变的。
所以让我们说你要做的
这在Python中意味着:创建一个具有值
1
的int
类型的对象并将名称a
绑定到它。 object 是int
的一个实例,值为1
,namea
指的是它。名称a
和它所引用的对象是不同的。现在假设您这样做
由于
int
是不可变的,因此这里发生的情况如下:a
引用的对象(它是一个int 和 id
0x559239eeb380
)0x559239eeb380
的值(它是1
)2
的新int
对象(它的对象 ID0x559239eeb3a0
)a
指向这个新对象a
引用对象0x559239eeb3a0
并且原始对象 (0x559239eeb380
) 不再被引用命名a
。如果没有任何其他名称引用原始对象,稍后它将被垃圾收集。自己尝试一下:
TL;DR
Python does not have unary increment/decrement operators (
--
/++
). Instead, to increment a value, useMore detail and gotchas
But be careful here. If you're coming from C, even this is different in python. Python doesn't have "variables" in the sense that C does, instead python uses names and objects, and in python
int
s are immutable.so lets say you do
What this means in python is: create an object of type
int
having value1
and bind the namea
to it. The object is an instance ofint
having value1
, and the namea
refers to it. The namea
and the object to which it refers are distinct.Now lets say you do
Since
int
s are immutable, what happens here is as follows:a
refers to (it is anint
with id0x559239eeb380
)0x559239eeb380
(it is1
)int
object with value2
(it has object id0x559239eeb3a0
)a
to this new objecta
refers to object0x559239eeb3a0
and the original object (0x559239eeb380
) is no longer refered to by the namea
. If there aren't any other names refering to the original object it will be garbage collected later.Give it a try yourself:
Python 没有这些运算符,但如果您确实需要它们,您可以编写具有相同功能的函数。
用法:
在函数内部,如果要更改局部变量,则必须添加 locals() 作为第二个参数,否则它将尝试更改全局变量。
另外,您还可以使用这些函数:
但在我看来,以下方法更清晰:
递减运算符:
我在将 javascript 翻译为 python 的模块中使用了这些函数。
Python does not have these operators, but if you really need them you can write a function having the same functionality.
Usage:
Inside a function you have to add locals() as a second argument if you want to change local variable, otherwise it will try to change global.
Also with these functions you can do:
But in my opinion following approach is much clearer:
Decrement operators:
I used these functions in my module translating javascript to python.
Wikipedia
因此,通过引入此类运算符,您将打破表达式/语句的拆分。
出于同样的原因,您无法
像其他一些不保留这种区别的语言一样进行书写。
Wikipedia
So by introducing such operators, you would break the expression/statement split.
For the same reason you can't write
as you can in some other languages where such distinction is not preserved.
是的,我也错过了 ++ 和 -- 功能。几百万行的 c 代码在我的旧头脑中根深蒂固了这种想法,而不是与之抗争......这是我拼凑出来的一个类,它实现了:
这里是:
你可以像这样使用它:
......已经有c,你可以这样做...
....或者只是...
...以及(重新)分配给整数...
...同时这将保持 c 作为类型计数器:
编辑:
然后出现了一些意想不到的(并且完全不需要的)行为,
...因为在该元组内部,没有使用 getitem() ,而是传递了对对象的引用到格式化功能。叹。所以:
......或者,更详细、更明确地表达我们真正想要发生的事情,尽管在实际形式中通过冗长反驳了(使用
cv
代替)......Yeah, I missed ++ and -- functionality as well. A few million lines of c code engrained that kind of thinking in my old head, and rather than fight it... Here's a class I cobbled up that implements:
Here 'tis:
You might use it like this:
...already having c, you could do this...
....or just...
...and for (re-)assignment into integer...
...while this will maintain c as type counter:
EDIT:
And then there's this bit of unexpected (and thoroughly unwanted) behavior,
...because inside that tuple, getitem() isn't what used, instead a reference to the object is passed to the formatting function. Sigh. So:
...or, more verbosely, and explicitly what we actually wanted to happen, although counter-indicated in actual form by the verbosity (use
c.v
instead)...python 中没有像 C 等语言那样的后/前递增/递减运算符。
我们可以将
++
或--
视为多个符号相乘,就像我们在数学 (-1) * (-1) = (+1)。例如
解析为
Which 翻译为
因为,
-
符号与-
符号相乘是+
最后,
There are no post/pre increment/decrement operators in python like in languages like C.
We can see
++
or--
as multiple signs getting multiplied, like we do in maths (-1) * (-1) = (+1).E.g.
Parses as
Which translates to
Because, multiplication of
-
sign with-
sign is+
And finally,
扩展亨利的答案,我实验性地实现了一个实现
a++
的语法糖库:hdytto 。使用方法很简单。从 PyPI 安装后,将
sitecustomize.py
: 放入您的项目目录中。然后,制作
main.py
:并通过
PYTHONPATH= 运行它。 python main.py
。 输出将是hdytto 将a++
替换为((a:=a+1)-1)
,因此它可以工作。解码脚本文件时,
Extending Henry's answer, I experimentally implemented a syntax sugar library realizing
a++
: hdytto.The usage is simple. After installing from PyPI, place
sitecustomize.py
:in your project directory. Then, make
main.py
:and run it by
PYTHONPATH=. python main.py
. The output will behdytto replaces
a++
as((a:=a+1)-1)
when decoding the script file, so it works.一个直接的解决方法
不再打字
另外,你可以直接写
由 小码哥发布于
并完成所有代码,然后搜索/替换“c++”,替换为“c=c+1”。只需确保正则表达式搜索已关闭即可。
A straight forward workaround
No more typing
Also, you could just write
c++
and finish all your code and then do search/replace for "c++", replace with "c=c+1". Just make sure regular expression search is off.