Python中的Python调用方法

Python calling method in class

我在这里打得比我的体重还重,但请容忍这个业余的Python。我是一个专业的PHP开发人员,我以前几乎没有接触过这种语言。

我要做的是在类中调用一个方法…听起来很简单?"self"指的是什么,以及在类内和类外调用此类方法的正确过程是什么,我对此完全困惑。

有人能给我解释一下,如何用变量RIGHT调用move方法。我尝试在几个"学习python"站点上研究这个问题,并在stackoverflow上搜索,但没有任何效果。任何帮助都将不胜感激。

下面的类在Scott的python脚本中工作,该脚本由终端GUI(URWID)访问。

我正在使用的函数是ScottWeston的导弹发射器python脚本,我正试图将其挂接到一个php web服务器上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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)


所有方法的第一个参数通常称为self。它指的是正在为其调用方法的实例。

假设你有:

1
2
3
4
5
6
class A(object):
    def foo(self):
        print 'Foo'

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

然后,做:

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

这个名字叫self,没有什么特别的,你可以做以下的事情:

1
2
3
4
5
6
class B(object):
    def foo(self):
        print 'Foo'

    def bar(this_object):
        this_object.foo()

然后,做:

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

在您的特定情况下:

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

(正如评论中所建议的,这里可能更合适!)

不过,您可以在模块级别声明所有常量,这样就可以:

1
dangerous_device.move(RIGHT)

然而,这将取决于您希望如何组织代码!


假设你有一个闪亮的foo课程。你有三个选择:

1)要在类的定义中使用类的方法(或属性):

1
2
3
4
5
6
7
8
9
10
11
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)您希望使用该类定义之外的类的方法(或属性)

1
2
3
4
5
6
7
8
9
10
11
12
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)要使用实例化类的方法(或属性):

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


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

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

如果你用其他语言编程了类,除了python,这类东西

1
2
class Foo:
    bar ="baz"

可能不熟悉。在Python中,类是对象的工厂,但它本身是对象;在其作用域中定义的变量附加到类,而不是类返回的实例。参照上面的bar,可以直接称之为Foo.bar;也可以通过类的实例访问类属性,比如Foo().bar

Im utterly baffled about what 'self' refers too,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> 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
>>>

当您acecss一个python对象的属性时,解释器会注意到,当looked up属性在类中并且是一个函数时,它应该返回一个"bound"方法,而不是函数本身。所有这些操作都是安排将实例作为第一个参数传递。