【问题标题】:Bit wise modification of integers in PythonPython中整数的按位修改
【发布时间】:2017-05-29 17:26:06
【问题描述】:

我正在编写的程序通过对整数应用二进制运算来操作整数(例如>>&|)。许多操作都在函数内部应用,并且为了使操作的结果在函数返回后保持不变,我将返回更改后的变量的副本。

类似:

updated = applyOp(original, amnt)

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

如果我不想返回整数的副本,而是希望在函数内对original 所做的更改在函数外持续存在,我想我可以创建某种包装类。还有其他选择吗?也许那些专门促进按位整数操作的?

【问题讨论】:

    标签: python-3.x function


    【解决方案1】:

    在 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
    

    同样,这是否有效取决于您正在尝试做什么。

    【讨论】:

    • 我对“同类方法”感兴趣。我试图看看这将如何解决这个问题——如果我用一个整数成员变量创建一个类并将该变量传递给一个类函数,我仍然会复制对成员变量的引用。这意味着我将无法重新分配它(我目前面临同样的问题)。
    • @Adam 我编辑添加了一个如何工作的示例。
    【解决方案2】:

    我猜你来自像 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 是一个不可变类型

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

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

    但是,一般来说,我建议您不要太在意实现细节和细微的性能差异,即使您很容易担心这样的事情。首先让代码运行良好并具有可读性,并在实际出现时处理可能的性能问题。

    【讨论】:

      猜你喜欢
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多