协慌网

登录 贡献 社区

Python 中递增和递减运算符的行为

我注意到可以将预增 / 减运算符应用于变量(例如++count )。它可以编译,但实际上并不会改变变量的值!

Python 中预增 / 减运算符(++ /-)的行为是什么?

为什么 Python 会偏离 C / C ++ 中看到的这些运算符的行为?

答案

++不是运算符。它是两个+运算符。 +运算符是身份运算符,不执行任何操作。 (澄清: +-一元运算符仅对数字有效,但我假设您不会期望假设的++运算符对字符串有效。)

++count

解析为

+(+count)

转化为

count

您必须使用稍长的+=运算符来完成您想做的事情:

count += 1

我怀疑++--运算符由于一致性和简单性而被遗漏了。我不知道 Guido van Rossum 做出决定的确切论据,但我可以想象一些论点:

  • 更简单的解析。从技术上讲,解析++count是模棱两可的,因为它可能是++count (两个一元+运算符),就像它可能是++count (一个一元++运算符)一样容易。它不是语法上的明显歧义,但确实存在。
  • 语言更简单。 ++只是+= 1的同义词。这是一种速记方法,因为 C 编译器很笨,并且不知道如何将a += 1优化a += 1大多数计算机拥有的inc指令。在优化编译器和字节码解释语言的今天,通常不赞成在一种语言中添加运算符以允许程序员优化其代码,尤其是在像 Python 这样设计成一致且易读的语言中。
  • 令人困惑的副作用。使用++运算符的语言中一个常见的新手错误是混合使用递增 / 递减运算符之间的差异(优先级和返回值),Python 喜欢消除语言 “陷阱”。 C中的预增 / 后增优先级问题非常棘手,并且非常容易弄乱。

当您想增加或减少时,通常需要对整数进行操作。像这样:

b++

但是在 Python 中,整数是不可变的 。那就是你不能改变他们。这是因为可以使用多个名称使用整数对象。尝试这个:

>>> b = 5
>>> a = 5
>>> id(a)
162334512
>>> id(b)
162334512
>>> a is b
True

上面的 a 和 b 实际上是同一对象。如果增加 a,也将增加 b。那不是你想要的。因此,您必须重新分配。像这样:

b = b + 1

或更简单:

b += 1

它将b重新分配给b+1 。那不是增量运算符,因为它不会增量b ,而是对其进行重新分配。

简而言之:Python 在这里的行为有所不同,因为它不是 C,也不是机器代码的底层包装,而是一种高级动态语言,在这种语言中,增量是没有意义的,也没有 C 中的必要,例如,每次有循环时在哪里使用它们。

尽管其他答案在显示仅仅+意义上是正确的(即,保留数字,如果为 1),则是正确的,但就其不解释会发生什么而言,它们是不完整的。

确切地说, +x计算为x.__pos__()++xx.__pos__().__pos__()

我可以想象一个非常奇怪的类结构(孩子们,不要在家做!),像这样:

class ValueKeeper(object):
    def __init__(self, value): self.value = value
    def __str__(self): return str(self.value)

class A(ValueKeeper):
    def __pos__(self):
        print 'called A.__pos__'
        return B(self.value - 3)

class B(ValueKeeper):
    def __pos__(self):
        print 'called B.__pos__'
        return A(self.value + 19)

x = A(430)
print x, type(x)
print +x, type(+x)
print ++x, type(++x)
print +++x, type(+++x)