Thomas C.
Thomas C.

Reputation: 85

python - Pass by value or by reference

I have an object with an attribute that is a list. For example:

obj.a = [3, 4, 5]

I would like to get the following behavior (but I can't manage to find a solution using magics/etc.) :

l = obj.a
obj.a[0] = 2

print(l) --> [3, 4, 5]
print(obj.a) ---> [2, 4, 5]

Of course I could simply use copy.deepcopy :

l = copy.deepcopy(obj.a) 

but for several reasons I would like, somehow, to make this step automatic/hide it for my users.

[EDIT] Using getattribute and returning a copy won't work of course:

import copy
class Test:
    def __init__(self):
         self.a = []

    def __getattribute__(self, attr):
        if attr == 'a':
            return copy.deepcopy(super(Test, self).__getattribute__(attr))

Any help appreciated !

Thnak you, Thomas

Upvotes: 1

Views: 288

Answers (3)

Sunil Lulla
Sunil Lulla

Reputation: 813

This is not possible without actually cloning the list to another list, you have to use copy() or deepcopy() depending on your requirement.

Upvotes: 0

Gautam Krishna R
Gautam Krishna R

Reputation: 2675

Simply use the following code...

l = list(obj.a)

this will allow you to copy a list to a new list

Upvotes: 0

BrenBarn
BrenBarn

Reputation: 251618

It's not possible to make the assignment l = obj.a make a copy of obj.a. As deceze said in a comment, you could make a a property that returns a copy of the value every time you access it, but that would, well, make a copy every time you access it, not just when you assign it to l. That's going to be inefficient, and probably not the behavior you want anyway

There's no way for obj or obj.a to tell the difference between something like this:

x = obj.a

and this:

obj.a[:2]

Whatever happens when you access obj.a, it's going to happen in both cases. You can't "look ahead" to see whether it's going to be assigned to a variable, just to copy it in that particular case.

Upvotes: 1

Related Questions