如何使不同的变量引用相同的值,同时仍允许直接操作?

时间:2015-05-04 17:52:06

标签: python python-3.x

使不同变量引用相同值的好方法是什么,同时仍允许直接操作,例如关于价值的*

所需代码的示例能够执行以下操作:

a = <Reference to integer 2>
b = a
print(a * b)  # Should show 4
<a update (not with assign using =) with reference to integer 3>
print(a * b)  # Should show 9

一个不太理想的解决方案是使用容器作为值,如命名空间,列表,字典等,但这需要引用如下.value之类的属性,因此不太理想:

import types

a = types.SimpleNamespace(value = 2)
b = a
print(a.value * b.value)  # Should show 4
a.value = 3
print(a.value * b.value)  # Should show 9

封装值的好方法是什么,所以直接操作仍然可行?

5 个答案:

答案 0 :(得分:5)

您可以创建一个覆盖乘法运算的类。

class Reference:
    def __init__(self, value):
        self.value = value
    def __mul__(self, other):
        return Reference(self.value * other.value)

这将允许您直接相互引用参考。例如,Reference(3) * Reference(4)生成Reference(12)

您可能还想覆盖__rmul__以及所有其他数字操作。 numbers中的抽象类可能对确保您不会忘记任何内容非常有用。

答案 1 :(得分:2)

你可以用课堂模拟你想要的行为,虽然有点笨拙和不优雅:

class reference:
  def __init__(self, num): self.num = num
  def get(self): return self.num
  def set(self, num): self.num = num
  def __mul__(self, other): return self.num * other
  def __div__(self, other): return self.num / other
  def __add__(self, other): return self.num + other
  def __sub__(self, other): return self.num - other

如果这些运营商超载,请执行以下操作:

a = reference(5)
b = a
print a.get()
print a * 4

打印

5
20

我意识到如果你想引用不同的类型,这是非常麻烦的,因为你必须重载每种类型所需的运算符,但是AFAIK它是你最接近模拟指针的。

或者,您只能在get类中包含set__init__reference,然后添加以后需要的重载函数:

class reference:
  def __init__(self, num): self.num = num
  def get(self): return self.num
  def set(self, num): self.num = num

a = reference(5)
reference.__mul__ = lambda self, num: self.num * num
print a * 4

以上打印20

答案 2 :(得分:1)

class Manager:
     def __init__(self,data):
         self.__dict__["data"] = data
     def __getattr__(self,attr):
         return getattr(self.data,attr)
     def __setattr__(self,attr,val):
         return setattr(self.data,attr,val)
     def set(self,val):
         self.__dict__["data"] = val


master = Manager(55)
print print master+5
print slave = master
print slave.set(88)
print slave + 10
print master+2

...
master_s = Manager("Test")
print master_s + " String"

...

master_c = Manager(MyCustomClass())
master_c.do_my_method()

可能?

答案 3 :(得分:0)

您可以使用对象周围的列表:

>>> a = [2]
>>> b = a
>>> print(a[0]*b[0])
4 
>>> a[0]+=1
>>> print(a[0]*b[0])
9

答案 4 :(得分:0)

To use the container classes, but still allow direct operations, you can overload the operators you wish to use for that type. As an example, define class SharedInt and write an overload for the * operator that takes two SharedInt's as arguments.

__mul__(self, other):
    return self.value * other.value