Python calling method in class


Question

I'm punching way above my weight here, but please bear with this Python amateur. I'm a PHP developer by trade and I've hardly touched this language before.

What I'm trying to do is call a method in a class...sounds simple enough? I'm utterly baffled about 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 to me, how to call the move method with the variable RIGHT. I've tried researching this on several 'learn python' sites and searches on StackOverflow, but to no avail. Any help will be appreciated.

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)
1
27
4/25/2017 9:05:25 AM

Accepted Answer

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!

56
12/29/2012 11:48:48 PM

Let's say you have a shiny Foo class. Well you have 3 options:

1) You want to use the method (or attribute) of a class inside the definition of that class:

class Foo(object):
    attribute1 = 1                   # class attribute (those don't use 'self' in declaration)
    def __init__(self):
        self.attribute2 = 2          # instance attribute (those are accessible via first
                                     # parameter of the method, usually called 'self'
                                     # which will contain nothing but the instance itself)
    def set_attribute3(self, value): 
        self.attribute3 = value

    def sum_1and2(self):
        return self.attribute1 + self.attribute2

2) You want to use the method (or attribute) of a class outside the definition of that class

def get_legendary_attribute1():
    return Foo.attribute1

def get_legendary_attribute2():
    return Foo.attribute2

def get_legendary_attribute1_from(cls):
    return cls.attribute1

get_legendary_attribute1()           # >>> 1
get_legendary_attribute2()           # >>> AttributeError: type object 'Foo' has no attribute 'attribute2'
get_legendary_attribute1_from(Foo)   # >>> 1

3) You want to use the method (or attribute) of an instantiated class:

f = Foo()
f.attribute1                         # >>> 1
f.attribute2                         # >>> 2
f.attribute3                         # >>> AttributeError: 'Foo' object has no attribute 'attribute3'
f.set_attribute3(3)
f.attribute3                         # >>> 3

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon