[英]When a list is used as a property in Python, the setter isn't actually called when you change an individual value in the list
Essentially what I'm trying to do is create a class that represents a robot arm. 本质上,我想做的是创建一个代表机械臂的类。
Inside of the arm there's a list that represents the joints, and my hope was that whenever those joints are 'set', it would transmit the values to a secondary microcontroller that controls the PWM signals that physically set the servos. 手臂内部有一个表示关节的列表,我希望每当“设置”这些关节时,它将这些值传输到辅助微控制器,该微控制器控制物理设置伺服器的PWM信号。
My problem is that when I only want to move 1 joint, but leave the others to be the same, I can't just say arm.joints[0] = 5
, because it sets the value but doesn't actually call the setter. 我的问题是,当我只想移动1个关节,而让其他关节保持不变时,我不能只说
arm.joints[0] = 5
,因为它设置了值但实际上并未调用setter 。
Is there a better way to structure this? 有没有更好的方法来构造它?
class RobotArm(object):
"""An object that resembles a robotic arm with n joints"""
def __init__(self):
# Empty list of zeros representing each joint
self.joints = [0]*5
@property
def joints(self):
return self.__joints
@joints.setter
def joints(self, vals):
print "setting values"
self.__joints = vals
self.serial_transmission(vals)
One solution is to use a custom list
: 一种解决方案是使用自定义
list
:
class Joints(list):
"""A custom list owned by another object. The owner should have
a before_set_joints() method and an after_set_joints() method.
"""
def __init__(self, owner, *args):
self.owner = owner
list.__init__(self, *args)
def __setitem__(self, key, value):
self.owner.before_set_joints()
list.__setitem__(self, key, value)
self.owner.after_set_joints()
# Define the onwer's methods cooperatively
class RobotArm(object):
def __init__(self):
self.__joints = Joints(self, [0] * 5) # make self the owner
def before_set_joints(self):
print 'setting values'
def after_set_joints(self):
self.serial_transmission(self.joints) # note a slight change here
The property definition can be just as before, but the setter needs to be modified: 属性定义可以和以前一样,但是需要修改设置器:
@joints.setter
def joints(self, vals):
self.before_set_joints()
self.__joints = Joints(self, vals)
self.after_set_joints()
Demo (I defined serial_transmission
to simply print "serial_transmission"
and the list content): 演示(我定义了
serial_transmission
以仅打印"serial_transmission"
和列表内容):
>>> arm = RobotArm()
>>> print(arm.joints)
[0, 0, 0, 0, 0]
>>> arm.joints = [1] * 5
setting joints
serial_transmission [1, 1, 1, 1, 1]
>>> arm.joints[0] = 5
setting joints
serial_transmission [5, 1, 1, 1, 1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.