![](/img/trans.png)
[英]Python: Extend class method and use the substituted in instance of the class
[英]Python - Extend Class Instance Method
我正在创建“框架”来控制六足动物。 所以(简化)我有一个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
...
还有一个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)
还有一个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
每当执行以下操作时,在HexLimb类中:self.femur.setAngle(30)我想调用self.calcPosition()来重新计算肢体的尖端位置。
我一直在搜寻,找不到任何答案...我做错了吗?
(在下面相应地编辑评论)
您的HexLimb
需要了解与它相连的HexBones
的位置,以计算其位置。 但是作为Servo
的HexBones
还需要了解它们所连接的HexLimb
,以便它们可以触发对肢体位置的重新计算。
一种解决方案是在HexBones
上HexBones
对其附加的HexLimb
的反向引用 。
在此示例中,我在两个骨骼的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()
采纳Lukas Graf的建议,为了保持Servo类的通用性,我对代码进行了一些更改。 基本上,Servo(及其子类HexBone本身)将回调函数引用作为init的可选参数(默认为None)。 最后调用Servo.setAngle时 ,将执行回调函数。 代码如下:
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.