Can a method in one class change an object in another class?

Discussion in 'Python' started by Stewart Midwinter, Mar 6, 2005.

  1. I've got an app that creates an object in its main class (it also
    creates a GUI). My problem is that I need to pass this object, a
    list, to a dialog that is implemented as a second class. I want to
    edit the contents of that list and then pass back the results to the
    first class. So my question is, can a method in one class change an
    object in another class?

    If the answer is no, I suppose I could pass in the list as an argument
    when I create the second class, then return the contents of the list
    when I end the methods in that second class.

    alternatively, I could make the list a global variable, then it would
    be available to all classes. I have a nagging feeling though that
    global variables are to be avoided on general principle. Is this
    correct?

    Here's a simple example app that tries to have one class change the
    object in another class. It doesn't give the behaviour I want,
    though.

    ---
    #objtest.py

    class first:
    def __init__(self):
    a = 'a'
    self.a = a
    print self.a

    def update(self):
    print 'initially, a is', self.a
    self.a = second(self.a)
    print 'afterwards, a is', self.a

    class second:
    def __init__(self, a):
    pass

    def __call__(self, a):
    a = 'aa'
    return a

    if __name__ == '__main__':
    app = first()
    app.update()

    thanks,
    --
    Stewart Midwinter

     
    Stewart Midwinter, Mar 6, 2005
    #1
    1. Advertising

  2. Here's what I came up with:

    #objtest.py


    class first:
    def __init__(self):
    a = 'a'
    self.a = a
    print self.a


    def update(self):
    print 'initially, a is', self.a
    self.a = second(self.a)
    print 'afterwards, a is', self.a.call(self.a)


    class second:
    def __init__(self, a):
    pass


    def call(self, a):
    a = 'aa'
    return a


    if __name__ == '__main__':
    app = first()
    app.update()

    Not sure if this is what you are wanting though.
     
    Harlin Seritt, Mar 6, 2005
    #2
    1. Advertising

  3. > I've got an app that creates an object in its main class (it also
    > creates a GUI). My problem is that I need to pass this object, a
    > list, to a dialog that is implemented as a second class. I want to
    > edit the contents of that list and then pass back the results to the
    > first class. So my question is, can a method in one class change an
    > object in another class?



    Sure it can. But your code shows that you suffer from a fundamental
    misunderstanding on how variables and values work in python. Don't be to
    worried about that, it happens to quite a few people.

    A variable in python is just a name refering to an object. So this

    >>> a = 'a'
    >>> b = a
    >>> print a, b

    a a


    will make a and b both refer to the string 'a'. Now assigning a different
    value to b will not affect the binding of a:

    >>> b = 10
    >>> print a, b

    a 10

    So that is the reason you obeserve the behaviour you've seen. Now the
    question is how to accomplish your desired goal? The answer is simple:
    don't rebind a value to a name - alter the value! In python, there is a
    distinction between mutable objects and immutable ones. Strings and numbers
    are of the latter kind, lists and dicts and objects of the former. So if we
    changed our example slighly, things start working as you'd expect:

    >>> a = ['a']
    >>> b = a
    >>> print a,b

    ['a'] ['a']
    >>> b[0] = 10
    >>> print a, b

    [10] [10]

    So if you pass the same _mutable_ object to two objects, and one of them
    changes it, the other one will see the changes:

    class A:
    def __init__(self):
    self.a_list = [0]

    class B:
    def __init__(self, l):
    self.l = l

    def foo(self):
    self.l.append(100)

    a = A()
    b = B(a.a_list)
    b.foo()
    print a.a_list

    -> [0, 100]


    There are some resources on the web that explain this in more thourough
    detail - but curretntly I have trouble finding them. Search this newsgroup.
    --
    Regards,

    Diez B. Roggisch
     
    Diez B. Roggisch, Mar 6, 2005
    #3
  4. Stewart Midwinter

    Lee Harr Guest

    On 2005-03-06, Stewart Midwinter <> wrote:
    > I've got an app that creates an object in its main class (it also
    > creates a GUI). My problem is that I need to pass this object, a
    > list, to a dialog that is implemented as a second class. I want to
    > edit the contents of that list and then pass back the results to the
    > first class. So my question is, can a method in one class change an
    > object in another class?
    >
    > If the answer is no, I suppose I could pass in the list as an argument
    > when I create the second class, then return the contents of the list
    > when I end the methods in that second class.
    >
    > alternatively, I could make the list a global variable, then it would
    > be available to all classes. I have a nagging feeling though that
    > global variables are to be avoided on general principle. Is this
    > correct?
    >
    > Here's a simple example app that tries to have one class change the
    > object in another class. It doesn't give the behaviour I want,
    > though.
    >


    Depends a bit on who is updating who and which is
    created first and which needs references to which.

    Maybe like this...

    > ---
    > #objtest.py
    >


    class first:
    def __init__(self, a):
    self.a = a
    print 'a initialized to', self.a
    self.updater = second(self)

    def update(self, a='aa'):
    print 'initially, a is', self.a
    self.updater.do_update(a)
    print 'afterwards, a is', self.a

    class second:
    def __init__(self, lst):
    self.lst = lst

    def do_update(self, a):
    self.lst.a = a


    if __name__ == '__main__':
    lst = first('a')
    lst.update()

    # or ...
    dlg = second(lst)
    lst.update('aaa')
     
    Lee Harr, Mar 6, 2005
    #4
  5. Stewart Midwinter

    Kent Johnson Guest

    Stewart Midwinter wrote:
    > I've got an app that creates an object in its main class (it also
    > creates a GUI). My problem is that I need to pass this object, a
    > list, to a dialog that is implemented as a second class. I want to
    > edit the contents of that list and then pass back the results to the
    > first class. So my question is, can a method in one class change an
    > object in another class?


    Diez and Lee have shown you two ways to do this.

    > If the answer is no, I suppose I could pass in the list as an argument
    > when I create the second class, then return the contents of the list
    > when I end the methods in that second class.


    This is almost what your example does, but you have made a small error. See below.

    > alternatively, I could make the list a global variable, then it would
    > be available to all classes. I have a nagging feeling though that
    > global variables are to be avoided on general principle. Is this
    > correct?


    Yes, it is correct.

    > Here's a simple example app that tries to have one class change the
    > object in another class. It doesn't give the behaviour I want,
    > though.
    >
    > ---
    > #objtest.py
    >
    > class first:
    > def __init__(self):
    > a = 'a'
    > self.a = a
    > print self.a
    >
    > def update(self):
    > print 'initially, a is', self.a
    > self.a = second(self.a)


    The line above is creating an instance of second and assigning it to self.a. What you want to do is
    create an instance of second, *call* it, and assign the result to self.a. So you should have
    self.a = second(self.a)(self.a)

    The self.a parameter passed to second is never used. If you change second.__init__ to
    def __init__(self):
    pass

    then the call in update() will be
    self.a = second()(self.a)

    Kent
    > print 'afterwards, a is', self.a
    >
    > class second:
    > def __init__(self, a):
    > pass
    >
    > def __call__(self, a):
    > a = 'aa'
    > return a
    >
    > if __name__ == '__main__':
    > app = first()
    > app.update()
    >
    > thanks,
    > --
    > Stewart Midwinter
    >
    >
     
    Kent Johnson, Mar 6, 2005
    #5
  6. Stewart Midwinter

    Guest

    thanks guys. Three good answers, each slightly different, but giving me
    good food for thought.

    Obviously my example was a trivial one, but I wanted to isolate the
    behaviour I'm seeing in my real app. I now have some good ideas for
    moving forward!

    cheers
    S
     
    , Mar 7, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    955
    Roedy Green
    Jan 28, 2008
  2. marekw2143
    Replies:
    3
    Views:
    1,390
    marekw2143
    Jul 25, 2009
  3. Robert Cohen
    Replies:
    3
    Views:
    295
    Andrew Durstewitz
    Jul 15, 2003
  4. J2M
    Replies:
    0
    Views:
    77
  5. Dan Stromberg
    Replies:
    1
    Views:
    93
    Steven D'Aprano
    Jun 7, 2014
Loading...

Share This Page