Search code examples
pythonclassmethods

Python calling method in class


I'm trying to call a method in a class. I don't know what 'self' refers to, and what is the correct procedure to call such a method inside a class and outside a class.

Could someone explain how to call the move method with the variable RIGHT?

The following class works in Scott's Python script which is accessed by a terminal GUI (urwid).

The function I'm working with is a Scott Weston's missile launcher Python script, which I'm trying to hook into a PHP web-server.

class MissileDevice:
  INITA     = (85, 83, 66, 67,  0,  0,  4,  0)
  INITB     = (85, 83, 66, 67,  0, 64,  2,  0)
  CMDFILL   = ( 8,  8,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0)
  STOP      = ( 0,  0,  0,  0,  0,  0)
  LEFT      = ( 0,  1,  0,  0,  0,  0)
  RIGHT     = ( 0,  0,  1,  0,  0,  0)
  UP        = ( 0,  0,  0,  1,  0,  0)
  DOWN      = ( 0,  0,  0,  0,  1,  0)
  LEFTUP    = ( 0,  1,  0,  1,  0,  0)
  RIGHTUP   = ( 0,  0,  1,  1,  0,  0)
  LEFTDOWN  = ( 0,  1,  0,  0,  1,  0)
  RIGHTDOWN = ( 0,  0,  1,  0,  1,  0)
  FIRE      = ( 0,  0,  0,  0,  0,  1)

  def __init__(self, battery):
    try:
      self.dev=UsbDevice(0x1130, 0x0202, battery)
      self.dev.open()
      self.dev.handle.reset()
    except NoMissilesError, e:
      raise NoMissilesError()

  def move(self, direction):
    self.dev.handle.controlMsg(0x21, 0x09, self.INITA, 0x02, 0x01)
    self.dev.handle.controlMsg(0x21, 0x09, self.INITB, 0x02, 0x01)
    self.dev.handle.controlMsg(0x21, 0x09, direction+self.CMDFILL, 0x02, 0x01)

Solution

  • The first argument of all methods is usually called self. It refers to the instance for which the method is being called.

    Let's say you have:

    class A(object):
    
        def foo(self):
            print('Foo')
       
        def bar(self, an_argument):
            print('Bar', an_argument)
    

    Then, doing:

    a = A()
    a.foo() #prints 'Foo'
    a.bar('Arg!') #prints 'Bar Arg!'
    

    There's nothing special about this being called self, you could do the following:

    class B(object):
    
        def foo(self):
            print('Foo')
    
        def bar(this_object):
            this_object.foo()
    

    Then, doing:

    b = B()
    b.bar() # prints 'Foo'
    

    In your specific case:

    dangerous_device = MissileDevice(some_battery)
    dangerous_device.move(dangerous_device.RIGHT) 
    

    (As suggested in comments MissileDevice.RIGHT could be more appropriate here!)

    You could declare all your constants at module level though, so you could do:

    dangerous_device.move(RIGHT)
    

    This, however, is going to depend on how you want your code to be organized!