-1

I have a class:

class a():
    def __init__(self):
        self.x = ["a", "b"]

and another class:

class b():
    def __init__(self, r):
        self.y = r
    def chg(self, a):
        self.y = a

I do:

>>> m = a()
>>> m.x
["a", "b"]
>>> n = b(m.x)
>>> n.y
["a", "b"]
>>> n.y = ["c", "d"]
>>> n.y
["c", "d"]
>>> m.x
["a", "b"]

Now why didn't m.x change to ["c", "d"]? How can I achieve this?

alwbtc
  • 28,057
  • 62
  • 134
  • 188

2 Answers2

2

Inheritance does not work this way in Python. However, I think your problem is mutability rather than inheritance itself. (You did not apply inheritance, I said these because you used it as a tag and in the title.)

Try it like this.

class a():
    def __init__(self):
        self.x = [5]

class b():
    def __init__(self, r):
        self.y = r
    def chg(self, a):
        self.y = a

m = a()
n = b(m.x)
n.y[0] = 99
print m.x
# Gives 99

This way, you only create one list, and use it with two different classes.

Note: You can think this as the pass by reference property in C-type languages.

Just to keep in mind, every assignment in Python is pass by reference because Python handles variables different than those languages. Read more about it. (This does not affect mutability.)

Edit: I see you edited you question. Now let me explain why your code does not work as you expected.

Mutability means you can change the elements inside a container, without assigning it to a new address in memory.

When you do,

n.y = ["c", "d"]

You do not change the list,(So you do not mutate the list) you just assign a new list to that variable name. To change the original list, you must alter every element by using list[index], so the element would be changed, but the list will be the same list. So you can do this

m = a()
n = b(m.x)

new_list = ["c", "d"]

for i, elem in enumerate(new_list):
    # This way you change every element one-by-one.
    n.y[i] = elem
    
print m.x

If you are not familiar with enumerate, study it immediately. But if you want to use simpler code(And more similar to C implementation.) You can make the assignments like this,

for i in range(len(new_list)):
    n.y[i] = new_list[i]
Community
  • 1
  • 1
Rockybilly
  • 2,938
  • 1
  • 13
  • 38
1

Oke so you need to do a little reading up on how memory works in python. What you do here:

>>> n = b(m.x)
>>> n.y
5

Is asking for the value m.x en sending it to the constructor of n. The value of m.x is 5 at that moment so 5 is passed to the constructor which then saves the NUMBER 5 in the object not the memory address to the variable m.x. Meaning that n is not linked in anyway to m. So if you where to update m.x, n would remain the same because the data for m is stored in a completely different place than that of n.

In a language like C you could pass the address of the variable to the constructor but this is not possible in Python. The only variables in python that use addresses are array's. So you might want to look into using single element array's if you really need this functionality.

Another tip I would give you is give your classes and variables proper names not just single character names!

Lasse Jacobs
  • 512
  • 7
  • 11