简体   繁体   中英

Creating a list of references to object attributes

The problem in the code is that Vector.numerical_vector is a list of copies of floats, but I need it to be list of references, so when Vector.vector[n].value is changed, Vector.numerical_vector[n] is changed to the same value as well.

Thanks for help in advance!

class Var:
    def __init__(self, val):
        self.value = float(val)

    def __float__(self):
        return self.value


class Vector:
    def __init__(self, vector):
        self.vector = vector
        self.numerical_vector = [float(x) for x in vector]

vars = [Var(i) for i in range(5)]
vector = Vector(vars)

You might want to employ a property for that.

class Vector:
    def __init__(self, vector):
        self.vector = vector
    @property
    def numerical_vector(self):
        return [x.value for x in self.vector]

Now vector.numerical_vector will always be synchronized. A drawback of this method is that it is recomputed each time you access it, some it may not be adapted to your specific application.

If performance is an issue, you could add __getitem__ and __setitem__ methods to Vector as follows:

class Vector:
    def __init__(self, vector):
        self.vector = vector
        self.numerical_vector = [float(x) for x in vector]
    def __getitem__(self, i):
        return self.vector[i]
    def __setitem__(self, i, val):
        self.vector[i] = val
        self.numerical_vector[i] = float(val)

In that case, if you set vector_instance[i] , then vector_instance.numerical_vector[i] will be also modified. But if you want to modify vector_instance.vector[i] directly, then synchronicity will be broken.

Depending on the use case, you can use either of the two approaches. Both have limitations but I don't think much more can be done.

There's no way to do that in python. What you could do is make numerical_vector an object that, when accessed, returns the float value of the corresponding vector item. Eg

class VectorWrapper:
    def __init__(self, vector):
        self.vector = vector

    def __getitem__(self, i):
        return float(self.vector[i])

and set self.numerical_vector = VectorWrapper(self.vector)

If you have to return a float representation when self.numerical_vector[i] is referenced,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM