<p>如果要自动跟踪所有创建的<code>AttributeBlock</code>对象,可以使用class属性:</p>
<pre><code>class AttributeBlock():
objects = []
def __init__(self, key, label, isClosed, isRequired, attributes):
self.key = key
self.label = label
self.isClosed = isClosed
self.isRequired = isRequired
self.attributes = attributes if attributes is not None else {}
self.objects.append(self)
</code></pre>
<p>一旦这样做,<code>add_attribute</code>可能会变成:</p>
<pre><code>def add_attribute_block(toybox = None, key = "" ):
if toybox is not None:
for obj in AttributeBlock.objects:
if obj.key == key:
toybox.attributes.append(obj)
break
</code></pre>
<p>也可以使用映射而不是类属性的列表:</p>
<pre><code>class AttributeBlock():
objects = {]
def __init__(self, key, label, isClosed, isRequired, attributes):
if key in self.objects:
# raise a custom exception
...
self.objects[key] = self
</code></pre>
<p>然后您可以简单地使用:</p>
<pre><code>def add_attribute_block(toybox = None, key = "" ):
if toybox is not None:
if key in AttributeBlock.objects:
toybox.attributes.append(AttributeBlock.objects[key])
</code></pre>
<p>如果要将列表对象的副本放入<code>ToyBox</code>,则必须更改创建方法以允许不将该副本放入全局列表。在这种情况下,代码将变成:</p>
<pre><code>class AttributeBlock():
objects = {}
dummy = {}
def __init__(self, key, label, isClosed, isRequired,
attributes, glob = None):
if glob is None:
glob = self.objects
if key in glob:
raise ValueError(str(key) + " already exists")
self.key = key
self.label = label
self.isClosed = isClosed
self.isRequired = isRequired
self.attributes = attributes if attributes is not None else {}
if glob is not self.dummy:
glob[key] = self
def copy(self):
return AttributeBlock(self.key, self.label, self.isClosed,
self.isRequired, self.attributes[:],
self.dummy)
</code></pre>
<p>一个虚拟类对象允许不在任何容器中存储新创建的对象,一个可选的<code>glob</code>参数允许将其存储在外部dict中。你知道吗</p>
<p><code>add_attribute_block</code>变成:</p>
<pre><code>def add_attribute_block(toybox = None, key = "", glob = None ):
if glob is None:
glob = AttributeBlock.objects
if toybox is not None:
if key in glob:
toybox.attributes.append(AttributeBlock.objects[key].copy())
</code></pre>
<p>使用copy方法在ToyBox中存储未存储在全局容器中的原始对象的副本。你知道吗</p>