That's standard Python behaviour. The obj
parameter of foo
is a 'handle' to the expression object which you pass in. Any changes that you make to the expression 'pointed to' by obj
will be visible outside foo
. But assigning obj
to something else just changes the handle. After the obj=ans
line, obj
no longer points to the expression you wanted to modify, but instead it points to the expression which was created on the first line of foo
.
This pure-Python example does the same thing:
def foo(obj):
bar = [5,6,7]
obj = bar
print(obj)
x = [1,2,3]
foo(x)
print(x)
See e.g. https://stackoverflow.com/questions/22054698/python-modifying-list-inside-a-function for more on this.
So the question now is how to change the object 'pointed to' by obj
. Just like with the list example, you have two options. Either do as in your bah
. Or directly manipulate 'elements of the object pointed to by obj
'. That is effectively what you do in kludge
, but yes, it is kludgy.
There are some methods to manipulate the object pointed to by obj
directly, but they are not ready for prime time yet (I'll update this answer later when I have more time). So for the time being, do as in bah
.