web-dev-qa-db-fra.com

Python en classe

Je frappe bien au-dessus de mon poids ici, mais je vous en prie, tenez avec ceci Python amateur. Je suis un PHP développeur par métier et je l’ai à peine touché cette langue avant.

Ce que j'essaie de faire, c'est d'appeler une méthode dans une classe ... cela semble assez simple? Je suis tout à fait déconcerté par le "moi" et par la procédure à suivre pour appeler une telle méthode à l'intérieur d'une classe et en dehors d'une classe.

Quelqu'un pourrait-il m'expliquer comment appeler la méthode move avec la variable RIGHT. J'ai essayé de le rechercher sur plusieurs sites "learn python" et sur StackOverflow, mais en vain. Toute aide serait appréciée.

La classe suivante fonctionne dans le script de Scott Python auquel on accède par une interface graphique de terminal (urwid).

La fonction avec laquelle je travaille est un lanceur de missiles Scott Weston Python, que j'essaie de connecter à un PHP serveur Web.

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)
27
kirgy

Le premier argument de toutes les méthodes est généralement appelé self. Il fait référence à l'instance pour laquelle la méthode est appelée.

Disons que vous avez:

class A(object):
    def foo(self):
        print 'Foo'

    def bar(self, an_argument):
        print 'Bar', an_argument

Ensuite, faire:

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

Il n'y a rien de spécial à ce que ceci s'appelle self, vous pouvez faire ce qui suit:

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

    def bar(this_object):
        this_object.foo()

Ensuite, faire:

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

Dans votre cas particulier:

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

(Comme suggéré dans les commentaires MissileDevice.RIGHT pourrait être plus approprié ici!)

Vous pouvez déclarez toutes vos constantes au niveau du module, vous pouvez donc:

dangerous_device.move(RIGHT)

Cela dépendra toutefois de la manière dont vous voulez que votre code soit organisé!

57
Thomas Orozco

Disons que vous avez une classe Foo brillante. Eh bien, vous avez 3 options:

1) Vous voulez utiliser la méthode (ou l'attribut) d'une classe dans la définition de cette classe:

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) Vous voulez utiliser la méthode (ou l'attribut) d'une classe en dehors de la définition de cette classe

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) Vous souhaitez utiliser la méthode (ou l'attribut) d'une classe instanciée:

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

Quelqu'un pourrait-il m'expliquer comment appeler la méthode move avec la variable RIGHT

>>> myMissile = MissileDevice(myBattery)  # looks like you need a battery, don't know what that is, you figure it out.
>>> myMissile.move(MissileDevice.RIGHT)

Si vous avez programmé dans une autre langue avec des classes, en plus de python, ce genre de chose

class Foo:
    bar = "baz"

est probablement inconnu. En python, la classe est une fabrique d'objets, mais elle-même est un objet. et les variables définies dans son étendue sont attachées à la classe, pas aux instances renvoyées par la classe. pour faire référence à bar, ci-dessus, vous pouvez simplement l'appeler Foo.bar; vous pouvez également accéder aux attributs de classe par le biais d'instances de la classe, comme Foo().bar.


Je suis tout à fait déconcerté par ce que "moi" désigne aussi,

>>> class Foo:
...     def quux(self):
...         print self
...         print self.bar
...     bar = 'baz'
...
>>> Foo.quux
<unbound method Foo.quux>
>>> Foo.bar
'baz'
>>> f = Foo()
>>> f.bar
'baz'
>>> f
<__main__.Foo instance at 0x0286A058>
>>> f.quux
<bound method Foo.quux of <__main__.Foo instance at 0x0286A058>>
>>> f.quux()
<__main__.Foo instance at 0x0286A058>
baz
>>>

Lorsque vous acquérez un attribut sur un objet python, l’interprète remarquera que, lorsque l’attribut recherché est sur la classe et qu’il s’agit d’une fonction, il doit renvoyer une méthode "liée" au lieu de la fonction elle-même, il s’agit de faire en sorte que l’instance soit transmise en tant que premier argument.