的属性设置为一个单独的列表元素

的属性设置为一个单独的列表元素

问题描述:

所有,我有一个几个列表对象类,定义如下:的属性设置为一个单独的列表元素

class Device: 

    def __init__(self): 
    self._channels = [None]*6 
    self._outputs = [None]*4 

    @property 
    def channels(self): 
    return self._channels 

    @channels.setter 
    def channels(self,value): 
    print("inside:",self.channels, value) 
    self._channels = value 

这里奇怪的是,在调用device.channels[1] = 'try'作品,但似乎并没有为'通过@ setter.channels函数。从下面的输出显示古怪:

device = Device() 
print("before:",device.channels) 
device.channels[1] = "try" 
print("after:",frmdeviced.channels) 
device.channels = "try2" 
print("check:",frm4d.channels) 

并且输出是:


before: [None, None, None, None, None, None] 
after: [None, 'try', None, None, None, None] # accessing single element is achieved
# , but not through @channels.setter!
inside: [None, 'try', None, None, None, None] try # only here we're
check: try2 # at least the setter works..

由于我需要逻辑时的channels单个元件被设置为运行,这种行为是有问题的。 我想知道导致这种行为的基础python机制是什么,它是如何被覆盖?是否有更多pythonic方式来实现设置/获取特定列表元素的目标?

+1

您需要在'channels'引用的对象上实现'__setitem__',在'Device'上执行它是没有意义的。 – jonrsharpe

+0

设置列表的一个元素是列表的一个操作,而不是交给列表的'Device'的操作。 – user2357112

device.channels[1] = "try"首先要访问"@property" getter方法,它返回一个列表,然后索引操作将在不在设备上的列表上执行。下面的例子证明它 -

>>> class Device: 

    def __init__(self): 
    self._channels = [None]*6 
    self._outputs = [None]*4 

    @property 
    def channels(self): 
    print("inside @property") 
    return self._channels 

    @channels.setter 
    def channels(self,value): 
    print("inside:",self.channels, value) 
    self._channels = value 


>>> device = Device() 
>>> device.channels[1] = "try" 
inside @property 
+0

@ user2357112,我以前看不到python3.x标记,现在我已经修改了我的答案。感谢您指出它 – AlokThakur

要仪器列表,创建一个仪表列表类。 Jupyter会话示例:

In [23]: class MonitoredList(list): 
      def __setitem__(self, index, value): 
       # run special logic here 
       print("setting index {} to {}".format(index, value)) 
       super(MonitoredList, self).__setitem__(index, value) 

In [24]: zz = MonitoredList([None]*6) 

In [25]: zz 
Out[25]: [None, None, None, None, None, None] 

In [26]: zz[3] = 42 
     setting index 3 to 42 

In [27]: zz 
Out[27]: [None, None, None, 42, None, None]