-3

I have two classes, classA and classB. classA has an attribute named image that contains data that is changing all the time. I want to be able to have an instance of classB that when I call a method on this instance, it can access self.image from classA. Unfortunately my attempts are failing.

Example code:

classA:
    def __init__(self):
        self.image = None #initialise
        analysis = classB(self)

    def doingstuff(self):
        self.image = somethingchanginghere()
        measurement = analysis.find_something_cool()
        print measurement

classB:
   def __init__(self, master):
       self.image = master.image #get a reference to the data from other class

   def do_something_cool(self):
       return type(self.image) #find something about the data at the point when method is called

main = classA()
main.doingstuff()

I get an error that says the data is still None, i.e. it's still in the state when it was initialised and the reference to classA from classB hasn't updated when self.image in classA changed. What have I done wrong?

Why does the working example give NoneType? I'm expecting a random number.

Sam
  • 1,052
  • 4
  • 13
  • 33
  • Your `print` statements suggest Python 2.x, but you don't inherit from `object` so your classes are "old-style", which is bad practice. Also, without `class` this is syntactically invalid as posted. Is `numpy` actually relevant here? Could you cut down further to a [mcve]? – jonrsharpe Jul 13 '16 at 09:35
  • 1
    Simply do `self.master = master` and use `self.master.image`. That will keep updating as the object updates. – deceze Jul 13 '16 at 09:37
  • Also start with the class B first, this is confusing ! in the __init__ of class A you are __init__ class B, are you trying to build a factory pattern ? – e-nouri Jul 13 '16 at 09:38
  • I was using numpy to make the working example testable by other people. Looks like it's been edited out anyway. I don't understand what you mean by 'old style' classes – Sam Jul 13 '16 at 09:38
  • @deceze perfect! I've got it working exactly how I want it now. Why wasn't it working the other way? – Sam Jul 13 '16 at 09:40
  • @SamuelBancroft 1. well you edited it out, as far as the edit history says. 2. http://stackoverflow.com/q/54867/3001761 – jonrsharpe Jul 13 '16 at 09:40
  • Because you're assigning a *value*, not a variable/attribute. If you assign `None` to `self.image`, then it'll stay that way. – deceze Jul 13 '16 at 09:41
  • @jonrsharpe Thanks for the link - I'l have a good read. deceze That makes much more sense thanks. – Sam Jul 13 '16 at 09:42

1 Answers1

1

There are two problems with your code:

  1. analysis is a variable local to the classA.__init__ and classA.doingstuff functions. If you wish to re-use it in other functions, you should define it as an attribute: self.analysis = classB(self).

  2. Python doesn't pass variables by reference. When you do analysis = classB(self), you create an object of classB, passing the object self as an argument. It is not a reference to the object, so classB.image is set and/or changed only once, in classB.__init__. If you wish to keep it updated, you should either do:

    classB:
        def __init__(self, master):
            self.master = master
    

    and then use master.image to get the image, or implement a classB method e.g.

    def update(self, image): 
        self.image = image
    

    and call it every time image changes.

Community
  • 1
  • 1
Nee
  • 566
  • 2
  • 17