2017-05-29 103 views
3

我正在编写的程序通过对它们应用二进制操作来操作整数(例如,>>,&,|)。许多操作都在函数内部应用,并且一旦函数返回,操作的结果就会一直存在,我将返回一个修改过的变量的副本。Python中整数的位修改

喜欢的东西:

updated = applyOp(original, amnt) 

def applyOp(original, amnt): 
    return original >> amnt 

如果我不想在函数中返回整的副本,而是想original所做的更改功能之外坚持,我想我可以创建某种包装类。还有其他选择吗?也许那些特别有利于位整数操作?

回答

2

在Python中,赋值给一个变量会改变变量绑定而不是特定内存位置的值。为了允许以您描述的方式进行修改,我相信您需要更改存储的数据而不是变量绑定。看看下面的例子:

a = 1 
b = a 
a = 2 

因为分配改变变量绑定,a现在绑定到2,但b仍难免1。你真的想要相反的行为,但(据我所知)这种行为在Python中不可用。

正如你所说,这将需要某种包装。然而,为此目的的课程并不是绝对必要的。最简单的方法之一是将数据放入列表中。拿这个例子:现在

a = [1] 
b = a 
a[0] = 2 

ab仍然包含相同的列表(因为没有重新分配是要么制造),等等a[0] == b[0] == 2。因此,一个有效的解决方案是始终将单个项目列表传递给函数,而不是直接传递值。

另一个答案可能是通过使两个方法具有相同的类,这当然可以共享成员变量来共享函数之间的数据。但是,我无法从有限的信息中看出这种方法是否适合您。

下面是如何可能的示例:

class MyClass: 
    def __init__(self): 
     self._value = 0; 

    def do_something(self): 
     # Do something with self._value 
     self._helper_function() 
     # Continue using self._value 

    def _helper_function(self): 
     # No need to pass the value in. It is accessible at self._value 

再次,这是否会工作取决于正是你正在尝试做的。

+0

我对“同类方法”感兴趣。我试图看看如何解决这个问题 - 如果我用一个整型成员变量创建一个类并将该变量传递给一个类函数,我仍然会对该成员变量进行引用。这意味着我无法重新分配它(我目前面临同样的问题)。 – Adam

+1

@Adam我编辑添加如何工作的例子。 – bytesized

0

我猜你是来自像C这样的语言,还没有熟悉Python的内部。

在python中,所有对象都通过引用传递。这意味着当你调用一个函数时不会进行复制。你可以通过你的对象看ID(存储位置)测试:

x = 0 

print(id(x)) 

def f(y): 
    print(id(y)) 

f(x) 

在这两种情况下,该ID是一样的,所以他们实际上是同一个对象,而不是一个副本。

起初这似乎很荒谬,因为如何改变价值的工作?

x = 1 
print(id(x)) 
x += 2 
print(id(x)) 

正如您所看到的,ID已更改。我们没有增加x,而是获得了一个全新的对象!这是因为int不可变类型

这意味着,当对对象进行操作时,它会返回一个新对象而不是修改自己。相反的是一个可以修改自己的可变类型。

蛇皮strfloatinttuple类型是不可变的,而dictlistset类型是可变的。

但是,一般情况下,我会建议您不要在意实施细节和细微的性能差异,即使这种担心这种情况的尝试也是如此。使代码运行良好并首先可读,并在实际出现问题时处理可能的性能问题。