Python wywołanie metody w klasie
Biję ponad moją wagę, ale proszę o cierpliwość dla amatora Pythona. Z zawodu jestem programistą PHP i prawie nie dotknąłem tego języka.
Próbuję wywołać metodę w klasie...brzmi prosto? Jestem całkowicie zdumiony tym, do czego odnosi się " ja " i jaka jest prawidłowa procedura wywoływania takiej metody wewnątrz klasy i poza klasą.Czy ktoś mógłby mi wyjaśnić , Jak wywołać metodę move
ze zmienną RIGHT
. Próbowałem zbadać to na kilku stronach "ucz się Pythona" i wyszukiwań w StackOverflow, ale bezskutecznie. Każda pomoc będzie mile widziana.
Następująca klasa działa w skrypcie Pythona Scotta, do którego dostęp ma terminal GUI (urwid).
Funkcja, z którą pracuję, to skrypt Pythona Scotta Westona z wyrzutnią rakiet, który próbuję podłączyć do serwera PHP.
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)
3 answers
Pierwszy argument wszystkich metod jest zwykle nazywany self
. Odnosi się do instancji, dla której metoda jest wywoływana.
Powiedzmy, że masz:
class A(object):
def foo(self):
print 'Foo'
def bar(self, an_argument):
print 'Bar', an_argument
Potem, robiąc:
a = A()
a.foo() #prints 'Foo'
a.bar('Arg!') #prints 'Bar Arg!'
Nie ma nic specjalnego w tym byciu nazwanym self
, możesz zrobić co następuje:
class B(object):
def foo(self):
print 'Foo'
def bar(this_object):
this_object.foo()
Potem, robiąc:
b = B()
b.bar() # prints 'Foo'
W twoim konkretnym przypadku:
dangerous_device = MissileDevice(some_battery)
dangerous_device.move(dangerous_device.RIGHT)
(zgodnie z sugestią w komentarzach MissileDevice.RIGHT
może być bardziej odpowiedni tutaj!)
Ty Może zadeklarować wszystkie stałe na poziomie modułu, więc możesz to zrobić:
dangerous_device.move(RIGHT)
To jednak będzie zależeć od tego, jak chcesz, aby Twój kod był zorganizowany!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-29 23:48:48
Powiedzmy, że masz błyszczącą klasę Foo. No masz 3 opcje:
1) chcesz użyć metody (lub atrybutu) klasy wewnątrz definicji tej klasy:
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) chcesz użyć metody (lub atrybutu) klasy poza definicją tej klasy
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) chcesz użyć metody (lub atrybutu) instancji klasy:
f = Foo()
f.attribute1 # >>> 1
f.attribute2 # >>> 2
f.attribute3 # >>> AttributeError: 'Foo' object has no attribute 'attribute3'
f.set_attribute3(3)
f.attribute3 # >>> 3
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 10:49:59
Mógłby mi ktoś wyjaśnić, jak wywołać metodę move ze zmienną RIGHT
>>> myMissile = MissileDevice(myBattery) # looks like you need a battery, don't know what that is, you figure it out.
>>> myMissile.move(MissileDevice.RIGHT)
Jeśli programowałeś w innym języku z klasami, oprócz Pythona, tego typu rzeczy
class Foo:
bar = "baz"
Jest prawdopodobnie nieznany. W Pythonie klasa jest fabryką obiektów, ale sama jest obiektem; zmienne zdefiniowane w jej zakresie są dołączane do klasy , a nie do instancji zwracanych przez klasę. aby odnieść się do bar
, powyżej, można go po prostu nazwać Foo.bar
; Możesz również uzyskać dostęp do atrybutów klasy poprzez instancje klasy, takie jak Foo().bar
.
Jestem całkowicie zdumiony tym, co " ja " również odnosi się,
>>> 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
>>>
Kiedy acecss atrybut na obiekcie Pythona, interpreter zauważy, gdy poszukiwany atrybut był na klasie i jest funkcją, że powinien zwrócić metodę "bound" zamiast samej funkcji. Wszystko to sprawia, że instancja ma być przekazywana jako pierwszy argument.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-29 23:43:52