Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument passing by reference to a class in python (á la C++), to modify it with the class methods

Tags:

python

In this case, I want that the program print "X = changed"

class Clase:
  def __init__(self,variable):
    self.var = variable
  def set_var(self):
    self.var = 'changed'

X = 'unchanged'
V = Clase(X)
V.set_var()

print "X = ",X
like image 691
diego Avatar asked Feb 11 '23 23:02

diego


2 Answers

All values are objects and are passed by reference in Python, and assignment changes the reference.

def myfunc(y):
     y = 13

x = 42       # x now points at the integer object, 42
myfunc(y)    # inside myfunc, y initially points to 42,
             # but myfunc changes its y to point to a
             # different object, 13
print(x)     # prints 42, since changing y inside myfunc
             # does not change any other variable

It's important to note here that there are no "simple types" as there are in other languages. In Python, integers are objects. Floats are objects. Bools are objects. And assignment is always changing a pointer to refer to a different object, whatever the type of that object.

Thus, it's not possible to "assign through" a reference and change someone else's variable. You can, however, simulate this by passing a mutable container (e.g. a list or a dictionary) and changing the contents of the container, as others have shown.

This kind of mutation of arguments through pointers is common in C/C++ and is generally used to work around the fact that a function can only have a single return value. Python will happily create tuples for you in the return statement and unpack them to multiple variables on the other side, making it easy to return multiple values, so this isn't an issue. Just return all the values you want to return. Here is a trivial example:

def myfunc(x, y, z):
    return x * 2, y + 5, z - 3

On the other side:

a, b, c = myFunc(4, 5, 6)

In practice, then, there is rarely any reason to need to do what you're trying to do in Python.

like image 178
kindall Avatar answered Feb 16 '23 02:02

kindall


In python list and dict types are global and are passed around by reference. So if you change the type of your variable X to one of those you will get the desired results.

[EDIT: Added use case that op needed]

class Clase:
  def __init__(self,variable):
    self.var = variable
  def set_var(self):
    self.var.test = 'changed'

class ComplicatedClass():
    def __init__(self, test):
        self.test = test

X = ComplicatedClass('unchanged')
print('Before:', X.test)

V = Clase(X)
V.set_var()

print("After:",X.test)

>>> Before: unchanged
>>> After: changed
like image 23
ashwinjv Avatar answered Feb 16 '23 04:02

ashwinjv