【发布时间】:2015-02-10 08:43:48
【问题描述】:
我正在尝试在 python (2) 中为对象集合建模。集合应该通过列表接口使对象的某个属性(整数、浮点数或任何不可变对象)可用。
(1)
>>> print (collection.attrs)
[1, 5, 3]
>>> collection.attrs = [4, 2, 3]
>>> print (object0.attr == 4)
True
我特别希望集合中的这个列表接口允许重新分配单个对象的属性,例如
(2)
>>> collection.attrs[2] = 8
>>> print (object2.attr == 8)
True
我确信这是一个非常频繁发生的情况,不幸的是我无法找到关于如何在 stackoverflow / google 等上实现它的令人满意的答案。
在幕后,我希望 object.attr 被实现为一个可变对象。不知何故,我还希望该集合包含对 object.attr 的“引用列表”,而不是各自引用的(不可变的)值本身。
请教您如何以优雅灵活的方式解决这个问题。
允许 (1) 但不允许 (2) 的可能实现是
class Component(object):
"""One of many components."""
def __init__(self, attr):
self.attr = attr
class System(object):
"""One System object contains and manages many Component instances.
System is the main interface to adjusting the components.
"""
def __init__(self, attr_list):
self._components = []
for attr in attr_list:
new = Component(attr)
self._components.append(new)
@property
def attrs(self):
# !!! this breaks (2):
return [component.attr for component in self._components]
@attrs.setter
def attrs(self, new_attrs):
for component, new_attr in zip(self._components, new_attrs):
component.attr = new_attr
!!!换行符 (2) 因为我们创建了一个新列表,其条目是对所有 Component.attr 值的引用,而不是对属性本身的引用。
感谢您的意见。
XMA
【问题讨论】:
-
为此,您可以将
System._components设为自定义类,以实现您想要的__setitem__行为。 -
完美,就像@filmor 在下面所做的那样。
标签: python reference pass-by-reference