[英]Python - Extend Class Instance Method
I'm creating the "framework" to control a Hexapod. 我正在创建“框架”来控制六足动物。 So (simplifying) I have a Servo class:
所以(简化)我有一个Servo课:
class Servo(object):
...
def setAngle(self, angle):
##Executes order to move servo to specified angle
##Returns False if not possible or True if OK
offsetAngle=self.offset+angle
if not self.checkServoAngle(offsetAngle):
#Angle not within servo range
return=False
else:
pwmvalue=self._convAngleToPWM(offsetAngle)
self._setPWM(pwmvalue)
self.angle=value
return=True
...
and a child HexBone class: 还有一个HexBone子类:
class HexBone(Servo):
## Servo.__init__ override:
def __init__(self, I2C_ADDRESS, channel, length, startAngle, reversed=False, minAngle=NULL, maxAngle):
self = Servo(I2C_ADDRESS, channel, reversed, minAngle, maxAngle)
#Setting bone length
self.length=length
#Positions bone in Starting Position
self.setAngle(startAngle)
and also a HexLimb class: 还有一个HexLimb类:
class HexLimb(object):
def __init__(self, I2C_ADDRESS, femurLength, tibiaLength, femurInv, tibiaInv):
#Setting precision of Limb Positioning
self.precision=1
#Setting i2c address and servo channels
self.femur = HexBone(I2C_ADDRESS, 1, femurLength, 45, femurInv, 5, 190)
self.tibia = HexBone(I2C_ADDRESS, 2, tibiaLength, 90, tibiaInv, 5, 190)
def calcPosition(self):
L1=self.femur.length
L2=self.tibia.length
try:
a1=90-self.femur.angle#########!!!!!!
a2=180-self.tibia.angle
self.x=L1*math.cos(math.radians(a1))+L2*math.cos(math.radians(a1-a2))
self.y=L1*math.sin(math.radians(a1))+L2*math.sin(math.radians(a1-a2))
except:
return False
else:
return True
In the HexLimb class whenever I do: self.femur.setAngle(30) I want to call self.calcPosition() to recalculate the limb's tip position. 每当执行以下操作时,在HexLimb类中:self.femur.setAngle(30)我想调用self.calcPosition()来重新计算肢体的尖端位置。
I've been searching all over and couldn't found any answer...Am I doing it the wrong way? 我一直在搜寻,找不到任何答案...我做错了吗?
(edited accordingly comments bellow) (在下面相应地编辑评论)
Your HexLimb
needs to know about the HexBones
attached to it to calculate its position. 您的
HexLimb
需要了解与它相连的HexBones
的位置,以计算其位置。 But the HexBones
, being Servo
s, also need to know about the HexLimb
they are attached to so that they can trigger a re-calculation of the limb's position. 但是作为
Servo
的HexBones
还需要了解它们所连接的HexLimb
,以便它们可以触发对肢体位置的重新计算。
One solution is to keep a back-reference on the HexBones
to the HexLimb
they're attached to. 一种解决方案是在
HexBones
上HexBones
对其附加的HexLimb
的反向引用 。
In this example, I create a back-reference called limb
in HexLimb.__init__()
on both bones - you could also call it parent
to be more generic about it. 在此示例中,我在两个骨骼的
HexLimb.__init__()
创建了一个称为limb
的反向引用-您也可以将其称为parent
以使其更通用。
from random import random
class Servo(object):
"""Servo controller"""
def __init__(self):
self.angle = 0
def set_angle(self, angle):
print "Setting angle to %s" % angle
self.angle = angle
# Let limb recalculate its position
self.limb.calc_position()
class HexBone(Servo):
"""A bone that can be attached to a limb and moved."""
def __init__(self, length):
super(HexBone, self).__init__()
self.length = length
# Will be assigned later when attached to a limb
self.limb = None
class HexLimb(object):
"""A limb consisting of several bones."""
def __init__(self):
self.femur = HexBone(42)
self.femur.limb = self
self.tibia = HexBone(30)
self.tibia.limb = self
def calc_position(self):
print "Calculating position..."
# Something that needs self.femur and self.tibia
self.x = self.femur.length * random()
self.y = self.tibia.length * random()
def extend(self):
self.tibia.set_angle(0) # extend knee
left_leg = HexLimb()
left_leg.extend()
Taking what Lukas Graf suggested i've changed the code a little bit in order to maintain the Servo class more general. 采纳Lukas Graf的建议,为了保持Servo类的通用性,我对代码进行了一些更改。 Basically Servo (and inherently its child class HexBone) take a callback function reference as an optional argument for init (which defaults to None).
基本上,Servo(及其子类HexBone本身)将回调函数引用作为init的可选参数(默认为None)。 When calling Servo.setAngle in the end this will execute the callback function.
最后调用Servo.setAngle时 ,将执行回调函数。 Code is as follows:
代码如下:
from random import random
class Servo(object):
"""Servo controller"""
def __init__(self, callback=None): #Servo takes a callback function as argument
self.angle = 0
self.callback=callback
def set_angle(self, angle):
print("Setting angle to %s" % angle)
self.angle = angle
# After angle set executes the callback function
if self.callback is not None: self.callback()
class HexBone(Servo):
"""A bone that can be attached to a limb and moved."""
def __init__(self, length, callback):
super(HexBone, self).__init__(callback)
self.length = length
class HexLimb(object):
"""A limb consisting of several bones."""
def __init__(self):
self.femur = HexBone(42, self.calc_position)
self.femur.limb = self
self.tibia = HexBone(30, self.calc_position)
self.tibia.limb = self
def calc_position(self):
print("Calculating position...")
# Something that needs self.femur and self.tibia
self.x = self.femur.length * random()
self.y = self.tibia.length * random()
def extend(self):
self.tibia.set_angle(0) # extend knee
left_leg = HexLimb()
left_leg.extend()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.