ObjectA calling ObjectB

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Midas

    ObjectA calling ObjectB

    In my "main" code, I would like to create two
    new objects (ObjectA and ObjectB) and have
    ObjectA directly call an ObjectB method. In
    order to do this I believe ObjectA must hold
    a reference to ObjectB. What about the name
    of the method? Must it be hardcoded in
    ObjectA?
  • Lawrence Oluyede

    #2
    Re: ObjectA calling ObjectB

    MidasOneTwo@hot mail.nospam.com (Midas) writes:
    [color=blue]
    > In my "main" code, I would like to create two
    > new objects (ObjectA and ObjectB) and have
    > ObjectA directly call an ObjectB method. In
    > order to do this I believe ObjectA must hold
    > a reference to ObjectB. What about the name
    > of the method? Must it be hardcoded in
    > ObjectA?[/color]

    You could simply do something like this:

    class A:
    def __init__(self):
    self.ObjectB = B()

    class B:
    def someMethod(self ):
    pass

    if __name__ == "__main__":
    ObjectA = A()
    ObjectA.ObjectB .someMethod()

    HTH

    --
    Lawrence "Rhymes" Oluyede
    Blogger ist ein Veröffentlichungs-Tool von Google, mit dem du ganz einfach deine Gedanken der Welt mitteilen kannst. Mit Blogger kannst du problemlos Texte, Fotos und Videos in deinem persönlichen Blog oder deinem Team-Blog veröffentlichen.

    Comment

    • Midas

      #3
      Re: ObjectA calling ObjectB

      Thanks for replying.
      It looks like you hardcoded the name ObjectB within ClassA. I'd like to avoid all hardcoding of names. In other words, I'd like ObjectA to be *told*, at run time, which object to call and which method to call.

      On Sat, 27 Dec 2003 21:42:05 +0100, Lawrence Oluyede wrote:
      [color=blue]
      >You could simply do something like this:
      >
      >class A:
      > def __init__(self):
      > self.ObjectB = B()
      >
      >class B:
      > def someMethod(self ):
      > pass
      >
      >if __name__ == "__main__":
      > ObjectA = A()
      > ObjectA.ObjectB .someMethod()[/color]

      Comment

      • Lawrence Oluyede

        #4
        Re: ObjectA calling ObjectB

        MidasOneTwo@hot mail.nospam.com (Midas) writes:
        [color=blue]
        > Thanks for replying. It looks like you hardcoded the name ObjectB
        > within ClassA. I'd like to avoid all hardcoding of names. In other
        > words, I'd like ObjectA to be *told*, at run time, which object to call
        > and which method to call.[/color]

        Mmm what do you mean with "to be told, at run time, which object
        to call and which method to call" ?

        Something like:

        if var == "a":
        # create object a and call method x
        else:
        # create object c and call method y

        ?

        --
        Lawrence "Rhymes" Oluyede
        Blogger ist ein Veröffentlichungs-Tool von Google, mit dem du ganz einfach deine Gedanken der Welt mitteilen kannst. Mit Blogger kannst du problemlos Texte, Fotos und Videos in deinem persönlichen Blog oder deinem Team-Blog veröffentlichen.

        Comment

        • Lee Harr

          #5
          Re: ObjectA calling ObjectB

          On 2003-12-27, Midas <MidasOneTwo@ho tmail.nospam.co m> wrote:[color=blue]
          > Thanks for replying.
          > It looks like you hardcoded the name ObjectB within ClassA. I'd like to avoid all hardcoding of names. In other words, I'd like ObjectA to be *told*, at run time, which object to call and which method to call.
          >
          > On Sat, 27 Dec 2003 21:42:05 +0100, Lawrence Oluyede wrote:
          >[color=green]
          >>You could simply do something like this:
          >>
          >>class A:
          >> def __init__(self):
          >> self.ObjectB = B()
          >>
          >>class B:
          >> def someMethod(self ):
          >> pass
          >>
          >>if __name__ == "__main__":
          >> ObjectA = A()
          >> ObjectA.ObjectB .someMethod()[/color][/color]



          class A:
          def __init__(self):
          self.b = B()
          def run_time(self, method_name):
          getattr(self.b, method_name)()

          class B:
          def foo(self):
          print 'foo!'

          a = A()
          a.run_time('foo ')


          Comment

          • Midas

            #6
            Re: ObjectA calling ObjectB

            By the way, thanks for assisting.

            Here's my plan:

            My main module would have three code sections:

            Part 1) Create 10 new assorted objects
            Part 2) Link up the objects, somehow, so they can communicate with each other directly, like parts of an electrical circuit.
            Part 3) Call the first object, which calls another, etc. like an electrical circuit.

            To change the circuit, I would only change part 2 and perhaps part 3.

            For example, ObjectX could have an input, for a string, and two outputs.
            If the input is "TurnOnS", it calls ObjectY.Input3
            If the input is "TurnOnT", it calls ObjectZ.Input7

            ObjectX would call either, ObjectY.Input3 or ObjectZ.Input7, because it was connected that way in part 2.

            I could then later change part 2 so ObjectX called either ObjectE.Input2 or ObjectF.Input9
            In other words, I could "re-wire" the circuit without changing anything in the objects.

            Midas

            On Sat, 27 Dec 2003 22:42:21 +0100, Lawrence Oluyede <raims@dot.co m> wrote:
            [color=blue]
            >Mmm what do you mean with "to be told, at run time, which object
            >to call and which method to call" ?[/color]

            Comment

            • Alan Gauld

              #7
              Re: ObjectA calling ObjectB

              On Sat, 27 Dec 2003 21:37:07 GMT, MidasOneTwo@hot mail.nospam.com
              (Midas) wrote:[color=blue]
              > It looks like you hardcoded the name ObjectB within ClassA.
              > I'd like to avoid all hardcoding of names. In other words,
              > I'd like ObjectA to be *told*, at run time, which object
              > to call and which method to call.[/color]

              While what you ask is possible it does kind of mess up the ideas
              of good OO design. For this to happen the caller of A's methods
              must know that A contains a B (not too bad but not pure OOD) and,
              much worse, know that B contains a method called foo which it
              tells A to call.

              The law of demeter suggests you should create a method on A that
              knows what to do, which may entail calling a method on B but it
              may equally entail looking up a third object which is a message
              dispatcher or ORB and getting it to do the work. The client of A
              shouldn't really know how A's internals work.

              So I guess I'm querying whether your design is as decoupled as it
              should be. The only thing that should know what A has inside is
              A... To do what you request something outside of A has to know
              about B, give it to A then request A to call a known method of
              the B givento A. Why not just have the external agency manage B
              directly since it is already tightly coupled to it?

              However I can equally guess that in the real world there may be
              some cases, especially in data driven applications where you want
              to dynamically control the internals of A, although even there
              creating a dispather mechanism may be worth the extra work...

              Alan G.
              Author of the Learn to Program website

              Comment

              • Midas

                #8
                Re: ObjectA calling ObjectB

                Thanks for assisting.

                What I'm trying to do is as follows:

                Part 1) Create 10 new assorted objects
                Part 2) Link up the objects, somehow, so they can communicate with each other directly, like parts of an electrical circuit.
                Part 3) Call the first object, which calls another, etc. like an electrical circuit.

                To change the circuit, I would only change part 2 and perhaps part 3.

                For example, ObjectX could have an input, for a string, and two outputs.
                If the input is "TurnOnS", it calls ObjectY.Input3
                If the input is "TurnOnT", it calls ObjectZ.Input7

                ObjectX would call either, ObjectY.Input3 or ObjectZ.Input7, because it was connected that way in part 2.

                I could then later change part 2 so ObjectX called either ObjectE.Input2 or ObjectF.Input9
                In other words, I could "re-wire" the circuit without changing anything in the objects.

                Comment

                • Alan Gauld

                  #9
                  Re: ObjectA calling ObjectB

                  On Sun, 28 Dec 2003 00:23:14 GMT, MidasOneTwo@hot mail.nospam.com
                  (Midas) wrote:[color=blue]
                  > Part 1) Create 10 new assorted objects
                  > Part 2) Link up the objects, somehow, so they can communicate with each other directly,
                  > like parts of an electrical circuit.[/color]

                  Sounds like you need a list or dictionary full of objects.
                  [color=blue]
                  > Part 3) Call the first object, which calls another, etc. like an electrical circuit.[/color]

                  That's a pretty unusual electrical circuit, but I think I see
                  what you mean...

                  You want a calling sequence that can be changed. That could be
                  another list or dictionary mapping inputs to responses.
                  [color=blue]
                  > To change the circuit, I would only change part 2 and perhaps part 3.[/color]

                  In which case to change the circuit you only need to change the
                  calling sequences.
                  [color=blue]
                  > For example, ObjectX could have an input, for a string, and two outputs.
                  > If the input is "TurnOnS", it calls ObjectY.Input3
                  > If the input is "TurnOnT", it calls ObjectZ.Input7[/color]

                  So far it looks more like a list of functions than a list of
                  objects.
                  [color=blue]
                  > ObjectX would call either, ObjectY.Input3 or ObjectZ.Input7,
                  > because it was connected that way in part 2.[/color]

                  You can either hard code Object X or have object X hold the tewo
                  lists I mentioned above. When you intialise ObjectX you need to
                  pass in the data to populate the lists.

                  The other, arguabluy more OO solution, would be to have the
                  inputs as message objects which know which objects to call. Thus
                  when you pass the "TurnOnS" message it has embedded within it a
                  reference to ObjectY.Input3 and a method called doit() or
                  somesuch. Then when object X receives the message it performs
                  some sanity/security checks then X tells the message to doit().
                  Probably a better solution would be to have the message objects
                  hold the sequence information but ObjectX hold the objects. X
                  then applies the sequence to its own objects.

                  That way when a message needs a new sequence you make the change
                  to the message that is affected. This encapsulates the change in
                  a much more logical way.

                  Lots of possibilities. Few of them actually requiring that you
                  pass around object and method names explicitly.

                  Alan g.

                  Author of the Learn to Program website

                  Comment

                  • Miki Tebeka

                    #10
                    Re: ObjectA calling ObjectB

                    Hello Midas,[color=blue]
                    > Part 1) Create 10 new assorted objects
                    > Part 2) Link up the objects, somehow, so they can communicate with each other directly, like parts of an electrical circuit.
                    > Part 3) Call the first object, which calls another, etc. like an electrical circuit.
                    >
                    > To change the circuit, I would only change part 2 and perhaps part 3.
                    >
                    > For example, ObjectX could have an input, for a string, and two outputs.
                    > If the input is "TurnOnS", it calls ObjectY.Input3
                    > If the input is "TurnOnT", it calls ObjectZ.Input7
                    >
                    > ObjectX would call either, ObjectY.Input3 or ObjectZ.Input7, because it was connected that way in part 2.
                    >
                    > I could then later change part 2 so ObjectX called either ObjectE.Input2 or ObjectF.Input9
                    > In other words, I could "re-wire" the circuit without changing anything in the objects.[/color]
                    [color=blue][color=green][color=darkred]
                    >>> class Wired:[/color][/color][/color]
                    def __init__(self):
                    self.sisters = {}
                    def register(self, msg, func, *args):
                    self.sisters[msg] = (func, args)
                    def process(self, msg):
                    func, args = self.sisters[msg]
                    func(*args)

                    [color=blue][color=green][color=darkred]
                    >>> w1 = Wired()
                    >>> w2 = Wired()
                    >>> def p(msg):[/color][/color][/color]
                    print msg
                    [color=blue][color=green][color=darkred]
                    >>> w2.woof = lambda m: p("Woof: %s" % m)
                    >>>
                    >>> w2.woof("X")[/color][/color][/color]
                    Woof: X[color=blue][color=green][color=darkred]
                    >>> w1.register("wo of", w2.woof, "HELLO")
                    >>>
                    >>> w1.process("woo f")[/color][/color][/color]
                    Woof: HELLO[color=blue][color=green][color=darkred]
                    >>>[/color][/color][/color]

                    HTH.
                    Miki

                    Comment

                    • Peter Otten

                      #11
                      Re: ObjectA calling ObjectB

                      Midas wrote:
                      [color=blue]
                      > Thanks for assisting.
                      >
                      > What I'm trying to do is as follows:
                      >
                      > Part 1) Create 10 new assorted objects
                      > Part 2) Link up the objects, somehow, so they can communicate with each
                      > other directly, like parts of an electrical circuit.
                      > Part 3) Call the first object, which calls another, etc. like an
                      > electrical circuit.
                      >
                      > To change the circuit, I would only change part 2 and perhaps part 3.
                      >
                      > For example, ObjectX could have an input, for a string, and two outputs.
                      > If the input is "TurnOnS", it calls ObjectY.Input3
                      > If the input is "TurnOnT", it calls ObjectZ.Input7
                      >
                      > ObjectX would call either, ObjectY.Input3 or ObjectZ.Input7, because it
                      > was connected that way in part 2.
                      >
                      > I could then later change part 2 so ObjectX called either ObjectE.Input2
                      > or ObjectF.Input9 In other words, I could "re-wire" the circuit without
                      > changing anything in the objects.[/color]

                      I think what you want is the observer pattern that is widely used, e. g. for
                      wiring the Java Swing GUI with the underlying data model.

                      Below is a toy example that connects some logical components. Rather than
                      invoking different methods on a per class basis, I store object references
                      directly and introduce a common interface for all classes, i. e. the
                      notify() method. As always in Python, the common base class is not a
                      necessity to make the compiler happy, but a means to reduce redundant code.

                      <demo.py>
                      class Gadget(object):
                      def __init__(self, name=None):
                      self._state = False
                      self.outputs = []
                      self.inputs = []
                      self.name = name
                      def addinputs(self, *inputs):
                      for i in inputs:
                      self.addinput(i )
                      def addoutput(self, o):
                      self.outputs.ap pend(o)
                      o.inputs.append (self)
                      def addinput(self, i):
                      self.inputs.app end(i)
                      i.outputs.appen d(self)
                      def addoutputs(self , *outputs):
                      for o in outputs:
                      self.addoutput( o)
                      def setstate(self, state):
                      if self._state != state:
                      self._state = state
                      self.changed()
                      def getstate(self):
                      return self._state
                      state = property(getsta te, setstate)
                      def changed(self):
                      for o in self.outputs:
                      o.notify(self)

                      class Not(Gadget):
                      def notify(self, sender):
                      self.state = not sender.state

                      class And(Gadget):
                      def notify(self, sender):
                      for i in self.inputs:
                      if not i.state:
                      self.state = False
                      break
                      else:
                      self.state = True

                      class Or(Gadget):
                      def notify(self, sender):
                      for i in self.inputs:
                      if i.state:
                      self.state = True
                      break
                      else:
                      self.state = False

                      class Input(Gadget):
                      def __str__(self):
                      return "\t%s is now %s" % (self.name, {False: "Off", True:
                      "On"}[self.state])

                      class Output(Input):
                      def changed(self):
                      print str(self)
                      def notify(self, sender):
                      self.state = sender.state

                      if __name__ == "__main__":
                      def state(v):
                      if v: return True
                      else: return False
                      def printState():
                      for g in ("Input:", ione, itwo, ithree, "Output:", red, green,
                      blue):
                      print g
                      one, two, three = False, False, False

                      # define the model
                      ione, itwo, ithree = [Input(name) for name in "one two three".split()]
                      gnot = Not()
                      gor = Or()
                      gand = And()
                      gnot.addinputs( ione)
                      gand.addinputs( gnot, itwo)
                      gor.addinputs(i one, itwo, ithree)

                      red, green, blue = [Output(name) for name in "red green blue".split()]
                      gor.addoutput(r ed) # one or two or three
                      gand.addoutput( green) # two and (not one)
                      gnot.addoutput( blue) # not one

                      #play with it
                      print "set one, two, three to True or False, e. g."
                      print "one=True"
                      print "type '?' to print the current state, 'quit' to quit"
                      while True:
                      cmd = raw_input()
                      if cmd == "quit":
                      break
                      elif cmd in ("?", "print"):
                      printState()
                      else:
                      try:
                      exec cmd
                      except:
                      pass
                      else:
                      ione.state = state(one)
                      itwo.state = state(two)
                      ithree.state = state(three)
                      </demo.py>

                      And now a sample session (note that I didn't bother to ensure a consistent
                      initial state):

                      <session>
                      set one, two, three to True or False, e. g.
                      one=True
                      type '?' to print the current state, 'quit' to quit
                      ?
                      Input:
                      one is now Off
                      two is now Off
                      three is now Off
                      Output:
                      red is now Off
                      green is now Off
                      blue is now Off
                      one=1
                      red is now On
                      two=1
                      three=1
                      one=two=three=0
                      green is now On
                      blue is now On
                      green is now Off
                      red is now Off
                      two=1
                      green is now On
                      red is now On
                      quit
                      </session>

                      Peter


                      Comment

                      • Peter Otten

                        #12
                        Re: ObjectA calling ObjectB

                        Peter Otten wrote:
                        [color=blue]
                        > And now a sample session (note that I didn't bother to ensure a consistent
                        > initial state):[/color]

                        Read: _manually_ ensure a consistent state for the given _example_. The
                        general case is definitely no toy problem.
                        Also, beware of loops in the wiring.

                        Peter

                        Comment

                        Working...