我如何使用预递增/递减操作符(++,——),就像在c++ ?
为什么++计数运行,但不改变变量的值?
我如何使用预递增/递减操作符(++,——),就像在c++ ?
为什么++计数运行,但不改变变量的值?
当前回答
博士TL;
Python没有一元的递增/递减操作符(——/++)。相反,要增加一个值,请使用
a += 1
更多细节和陷阱
但这里要小心。如果你来自C语言,在python中甚至这一点都是不同的。Python没有C语言那样的“变量”,相反,Python使用名称和对象,并且在Python中int是不可变的。
假设你有
a = 1
这在python中意味着:创建一个int类型的值为1的对象,并将名称a绑定到它。对象是int的一个实例,值为1,名称a指向它。名称a和它所引用的对象是不同的。
现在让我们假设你知道
a += 1
由于int型是不可变的,这里发生的情况如下:
查找a所指向的对象(它是一个int型,id为0x559239eeb380) 查找对象0x559239eeb380的值(它是1) 将该值加1 (1 + 1 = 2) 创建一个值为2的新int对象(对象id为0x559239eeb3a0) 将名称a重新绑定到这个新对象 现在a引用对象0x559239eeb3a0,原始对象(0x559239eeb380)不再被名称a引用。如果没有任何其他名称引用原始对象,它将在以后被垃圾收集。
你自己试试吧:
a = 1
print(hex(id(a)))
a += 1
print(hex(id(a)))
其他回答
在Python中,表达式和语句之间有严格的区别 与Common Lisp、Scheme或 Ruby。
维基百科
因此,通过引入这样的操作符,可以打破表达式/语句的分割。
和你不能写作的原因一样
if x = 0:
y = 1
就像在其他一些不保留这种区别的语言中一样。
虽然其他答案是正确的,因为它们表明了单纯的+通常做什么(即,保持数字的原样,如果它是1),他们是不完整的,因为他们没有解释发生了什么。
确切地说,+ x等于x.__pos__()和+ + x x.__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)
是的,我也错过了++和-功能。几百万行c代码让这种想法在我的老头脑中根深蒂固,而不是与它斗争……这里是一个我拼凑起来实现的类:
pre- and post-increment, pre- and post-decrement, addition,
subtraction, multiplication, division, results assignable
as integer, printable, settable.
这里的是:
class counter(object):
def __init__(self,v=0):
self.set(v)
def preinc(self):
self.v += 1
return self.v
def predec(self):
self.v -= 1
return self.v
def postinc(self):
self.v += 1
return self.v - 1
def postdec(self):
self.v -= 1
return self.v + 1
def __add__(self,addend):
return self.v + addend
def __sub__(self,subtrahend):
return self.v - subtrahend
def __mul__(self,multiplier):
return self.v * multiplier
def __div__(self,divisor):
return self.v / divisor
def __getitem__(self):
return self.v
def __str__(self):
return str(self.v)
def set(self,v):
if type(v) != int:
v = 0
self.v = v
你可以这样使用它:
c = counter() # defaults to zero
for listItem in myList: # imaginary task
doSomething(c.postinc(),listItem) # passes c, but becomes c+1
...已经有了c,你可以这样做。
c.set(11)
while c.predec() > 0:
print c
....或者只是……
d = counter(11)
while d.predec() > 0:
print d
...和(重)赋值为整数…
c = counter(100)
d = c + 223 # assignment as integer
c = c + 223 # re-assignment as integer
print type(c),c # <type 'int'> 323
...而这将保持c作为类型计数器:
c = counter(100)
c.set(c + 223)
print type(c),c # <class '__main__.counter'> 323
编辑:
还有一点出乎意料(完全不受欢迎)的行为,
c = counter(42)
s = '%s: %d' % ('Expecting 42',c) # but getting non-numeric exception
print s
...因为在该元组中,没有使用getitem(),而是将对象的引用传递给格式化函数。叹息。所以:
c = counter(42)
s = '%s: %d' % ('Expecting 42',c.v) # and getting 42.
print s
...或者,更详细,更明确地说,我们实际上想要发生什么,尽管在实际形式中与冗长相反(使用c.v代替)……
c = counter(42)
s = '%s: %d' % ('Expecting 42',c.__getitem__()) # and getting 42.
print s
博士TL;
Python没有一元的递增/递减操作符(——/++)。相反,要增加一个值,请使用
a += 1
更多细节和陷阱
但这里要小心。如果你来自C语言,在python中甚至这一点都是不同的。Python没有C语言那样的“变量”,相反,Python使用名称和对象,并且在Python中int是不可变的。
假设你有
a = 1
这在python中意味着:创建一个int类型的值为1的对象,并将名称a绑定到它。对象是int的一个实例,值为1,名称a指向它。名称a和它所引用的对象是不同的。
现在让我们假设你知道
a += 1
由于int型是不可变的,这里发生的情况如下:
查找a所指向的对象(它是一个int型,id为0x559239eeb380) 查找对象0x559239eeb380的值(它是1) 将该值加1 (1 + 1 = 2) 创建一个值为2的新int对象(对象id为0x559239eeb3a0) 将名称a重新绑定到这个新对象 现在a引用对象0x559239eeb3a0,原始对象(0x559239eeb380)不再被名称a引用。如果没有任何其他名称引用原始对象,它将在以后被垃圾收集。
你自己试试吧:
a = 1
print(hex(id(a)))
a += 1
print(hex(id(a)))
Python没有这些操作符,但如果你真的需要它们,你可以编写一个具有相同功能的函数。
def PreIncrement(name, local={}):
#Equivalent to ++name
if name in local:
local[name]+=1
return local[name]
globals()[name]+=1
return globals()[name]
def PostIncrement(name, local={}):
#Equivalent to name++
if name in local:
local[name]+=1
return local[name]-1
globals()[name]+=1
return globals()[name]-1
用法:
x = 1
y = PreIncrement('x') #y and x are both 2
a = 1
b = PostIncrement('a') #b is 1 and a is 2
在函数内部,如果你想改变局部变量,你必须添加locals()作为第二个参数,否则它将尝试改变全局变量。
x = 1
def test():
x = 10
y = PreIncrement('x') #y will be 2, local x will be still 10 and global x will be changed to 2
z = PreIncrement('x', locals()) #z will be 11, local x will be 11 and global x will be unaltered
test()
还有这些函数,你可以做:
x = 1
print(PreIncrement('x')) #print(x+=1) is illegal!
但在我看来,以下方法更清晰:
x = 1
x+=1
print(x)
递减运算符:
def PreDecrement(name, local={}):
#Equivalent to --name
if name in local:
local[name]-=1
return local[name]
globals()[name]-=1
return globals()[name]
def PostDecrement(name, local={}):
#Equivalent to name--
if name in local:
local[name]-=1
return local[name]+1
globals()[name]-=1
return globals()[name]+1
我使用这些函数在我的模块翻译javascript到python。