python 增加 int 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1135335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:33:10  来源:igfitidea点击:

increment int object

pythonint

提问by Anurag Uniyal

Is there a way in python to increment int object in place, int doesn't seem to implement __iadd__so += 1 actually returns a new object

python中有没有办法在适当的位置增加int对象,int似乎没有实现__iadd__所以+= 1实际上返回一个新对象

>>> n=1
>>> id(n)
9788024
>>> n+=1
>>> id(n)
9788012

What I want is n to remain pointing to same object.

我想要的是 n 保持指向同一个对象。

Purpose: I have class derived from int and I want to implement C type '++n' operator for that class

目的:我有从 int 派生的类,我想为该类实现 C 类型的 '++n' 运算符

Conclusion: ok as int is immutable there is no way, looks like i will have to write my own class something like this

结论:好的,因为 int 是不可变的,没有办法,看起来我将不得不编写自己的类

class Int(object):
    def __init__(self, value):
        self._decr = False
        self.value = value

    def __neg__(self):
        if self._decr:
            self.value -= 1
        self._decr = not self._decr
        return self

    def __str__(self):
        return str(self.value)

    def __cmp__(self, n):
        return cmp(self.value, n)

    def __nonzero__(self):
        return self.value

n = Int(10)
while --n:
    print n

采纳答案by Arkady

ints are immutable, so you'll have to build your own class with all the int's methods if you want a "mutable int"

ints 是不可变的,所以如果你想要一个“可变的 int”,你必须用所有 int 的方法构建你自己的类

回答by Robpol86

You can use ctypes as mutable integers. Choosing the right ctype will be important though, as they limit the size of integer they can carry.

您可以将 ctypes 用作可变整数。不过,选择正确的 ctype 很重要,因为它们限制了它们可以携带的整数的大小。

>>> from ctypes import c_int64
>>> num = c_int64(0)
>>> id(num)
4447709232
>>> def increment(number):
...     number.value += 1
... 
>>> increment(num)
>>> increment(num)
>>> increment(num)
>>> num.value
3
>>> id(num)
4447709232
>>> 

More info: https://docs.python.org/2/library/ctypes.html#fundamental-data-types

更多信息:https: //docs.python.org/2/library/ctypes.html#fundamental-data-types

回答by Markus

If you absolutely have to get that code to work, here's a dirty method, where an instance method moves up a frame and overwrites its own locals entry. Wouldn't recommend. (like, really not. I'm not even sure what that does. What happens to the old instance? I don't know enough about frames...). Really, I'm only posting this because everyone said it's impossible, when in reality it's just ridiculously bad form. ;-)

如果您绝对必须让该代码工作,这里有一个脏方法,其中一个实例方法向上移动一个框架并覆盖它自己的本地条目。不推荐。(就像,真的不是。我什至不确定那是做什么的。旧实例会发生什么?我对帧的了解还不够......)。真的,我发布这个只是因为每个人都说这是不可能的,而实际上它的形式非常糟糕。;-)

import sys
class FakeInt(int):
    def __init__(self, *arg, **kwarg):
        self._decr = False
        int.__init__(self, *arg, **kwarg)
    def __neg__(self):
        if self._decr:

            upLocals = sys._getframe(1).f_locals
            keys, values = zip(*upLocals.items())
            i = list(values).index(self)

            result = FakeInt(self-1)
            upLocals[keys[i]]=result

            return result
        self._decr = not self._decr
        return self

A = FakeInt(10)
while --A:
    print A,

outputs:

输出:

9 8 7 6 5 4 3 2 1

回答by Carl Smith

You can put an immutable object inside a mutable container; lists are easiest.

您可以将不可变对象放入可变容器中;列表是最简单的。

This code prints 0, demonstrating the problem:

此代码打印0,说明问题:

a = 0       # `a` points to a new int (a `0`)
b = a       # `b` points to the same thing as `a` (the `0`)
b = 1       # `b` points to a new int (a `1`)
print(a)    # `a` still points to the same thing (the `0`)

If you put the int in a list, but otherwise use the same code as before, you can get the effect of having a mutable int (though it's the list that is being mutated really):

如果您将 int 放入列表中,但使用与之前相同的代码,则可以获得具有可变 int 的效果(尽管实际上是列表发生了突变):

a = [0]        # `a` points to a new `0` inside a new list
b = a          # `b` points to the same thing as `a` (the list)
b[0] = 1       # the list that `a` and `b` point to is mutated
print(a[0])    # `a[0]` points to the same object as `b[0]` (the `1`)

In practice, you should structure your data so that the above 'trick' is redundant. The examples should not be used directly, but should help you figure out what to do.

在实践中,您应该构建您的数据,以便上述“技巧”是多余的。这些示例不应直接使用,但应该可以帮助您弄清楚该怎么做。

回答by Ryan

It would probably be easier to create a class that implements the int methods and wraps an internal integer.

创建一个实现 int 方法并包装内部整数的类可能会更容易。

回答by Fake Code Monkey Rashid

Yes, the short answer is that, ints are immutable.

是的,简短的回答是,整数是不可变的。

回答by rdutta

I had a similar issue today and came up with a class called IterInt that lets you increment or decrement in place using "+" and "-" decorators.

我今天遇到了类似的问题,并提出了一个名为 IterInt 的类,它可以让您使用“+”和“-”装饰器就地递增或递减。

Usage:

用法:

x = IterInt()

print x
# result: 0

print +x
# result: 1

print +x
# result: 2

print +x
# result: 3

print -x
# result: 2

print -x
# result: 1

print -x
# result: 0

In my case I had a situation where I wanted to modify an application's existing menu by inserting several command items after a specific index. The provided API I'm using has an "addCommand" function that can take an index at which to insert.

在我的情况下,我想通过在特定索引后插入几个命令项来修改应用程序的现有菜单。我使用的提供的 API 有一个“addCommand”函数,它可以获取要插入的索引。

Consider this pseudo code where menu has commands a through g, something like menu = [a, f, g], and I want to insert b-e at index 1-4

考虑这个伪代码,其中 menu 有命令 a 到 g,类似于 menu = [a, f, g],我想在索引 1-4 处插入

idx = 1
menu.addCommand(b, index=idx)
idx += 1
menu.addCommand(c, index=idx)
idx += 1
menu.addCommand(d, index=idx)
idx += 1
menu.addCommand(e, index=idx)
idx += 1

# result: menu = [a, b, c, d, e, f]

It would be nice if I could write it so idx increments in place like c where I could do idx++, but functions do not allow python's idx+=1 methodology in arguments.

如果我可以编写它以便 idx 在适当的位置增加 idx 会很好,我可以在其中执行 idx++,但是函数不允许在参数中使用 python 的 idx+=1 方法。

Solution:

解决方案:

class IterInt(int):
"""
This function will return the next integer from the init_value starting point or 0 if None.
Each subsequent call to increment returns the next value
:param init_value:
:return:
"""
def __init__(self, init_value=None):
    if init_value is None:
        init_value = 0

    if init_value is not None:
        self.increment_value = init_value
    self.increment_value = init_value

def __pos__(self):
    self.increment_value += 1
    return self.increment_value

def __neg__(self):
    self.increment_value -= 1
    return self.increment_value


idx = IterInt(1)
menu.addCommand(b, index=+idx)
menu.addCommand(c, index=+idx)
menu.addCommand(d, index=+idx)
menu.addCommand(e, index=+idx)

# result: menu = [a, b, c, d, e, f]