我需要一些指导,说明如何正确设置我正在尝试做的事情。 我有一个名为Attribute Block的类,然后我将用它来创建3个或4个Attribute块对象。如下所示...
class AttributeBlock():
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 {}
3个attributeBlock对象
AttributeBlock(
key="Sphere",
isRequired=True,
attributes=[
''' Other class objects '''
BoolProperty("ishidden", False, "Hidden"),
]
)
AttributeBlock(
key="Box",
isRequired=True,
attributes=[
''' Other class objects '''
BoolProperty("ishidden", True, "Hidden"),
]
)
AttributeBlock(
key="Circle",
isRequired=False,
attributes=[
''' Other class objects '''
BoolProperty("ishidden", True, "Hidden"),
]
)
我当时想要做的是能够将这些AttributeBlock中的一个添加到Object中,确保在添加它时,它是AttributeBlock的新实例,因此其子属性对象是新实例。
这是我将添加属性块的对象。
class ToyBox():
def __init__(self, name="", attributes=[]):
self.name = name
self.attributes = attributes[:]
newToyBox = ToyBox()
newToyBox.name = "Jimmy"
伪代码
def add_attribute_block(toybox = None, key = "" ):
if an AttributeBlock with the matching key exists:
add it to toybox.attributes
add_attribute_block( newToyBox, "Box" )
print newToyBox
>>
ToyBox
name="Jimmy"
attributes=[
AttributeBlock(
key="Box",
isRequired=True,
attributes=[
BoolProperty("ishidden", True, "Hidden"),
]
),
AttributeBlock(
key="Sphere",
isRequired=True,
attributes=[
BoolProperty("ishidden", True, "Hidden"),
]
)
]
答案 0 :(得分:1)
如果您想确保添加到ToyBox的属性实例是副本,最简单的方法是使用standard copy module
import copy
...
class ToyBox(object):
...
def add_attribute(self, attribute):
self.attributes.append(copy.deepcopy(attribute))
答案 1 :(得分:1)
如果要自动跟踪所有已创建的AttributeBlock
个对象,可以使用类属性:
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)
完成此操作后,add_attribute
可能会变为:
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
您还可以使用映射而不是列属性作为类属性:
class AttributeBlock():
objects = {]
def __init__(self, key, label, isClosed, isRequired, attributes):
if key in self.objects:
# raise a custom exception
...
self.objects[key] = self
然后你可以简单地使用:
def add_attribute_block(toybox = None, key = "" ):
if toybox is not None:
if key in AttributeBlock.objects:
toybox.attributes.append(AttributeBlock.objects[key])
如果要在ToyBox
中放置列表对象的副本,则必须更改创建方法以允许不将该副本放入全局列表中。在这种情况下,代码将变为:
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)
使用允许不在任何容器中存储新创建的对象的伪类对象,以及允许将其存储在外部字典中的可选glob
参数。另请注意精确使用copy
的{{1}}方法。
dummy
变为:
add_attribute_block
使用copy方法存储在ToyBox中,原始对象的副本未存储在全局容器中。
答案 2 :(得分:1)
如果我理解正确,您希望每个ToyBox
实例包含AttributeBlock
实例的列表,不检查其他此类对象
名单中还有相同的名称。
class AttributeBlock():
def __init__(self, key): # demo, add the other parameters/attrs
self.key = key
def __str__(self):
return self.key # add the other parameters/attrs
class ToyBox(object):
def __init__(self):
self.attributes = []
def add_attr(self, a):
gen = (attr for attr in self.attributes if attr.key == a.key)
try:
next(gen)
except StopIteration:
self.attributes.append(a)
def __str__(self):
return ','.join(map(str,self.attributes))
现在我们可以做到
>>> toy = ToyBox()
>>> toy.add_attr(AttributeBlock("Box"))
>>> toy.add_attr(AttributeBlock("Sphere"))
>>> toy.add_attr(AttributeBlock("Box"))
>>> print toy
Box,Sphere
正如您所注意到的那样,使add_attribute
函数成为ToyBox
BTW,如果attributes
列表中的对象数量很大,最好使用字典:
class ToyBox(object):
def __init__(self):
self.attributes = dict()
def add_attr(self, a):
if a.key not in self.attributes:
self.attributes[a.key] = a
def __str__(self):
return ','.join(map(str,self.attributes.values()))
注意:如果您想保留添加对象的顺序,请改用OrderedDict
答案 3 :(得分:1)
将所有属性块放在列表中。
blocks = []
// add your AttributeBlocks to this list
blocks.append(block1)
blocks.append(block2)
blocks.append(block3)
然后很容易。
def add_attribute_block(toybox, key):
#loop over list of blocks and find the block with that key
for block in blocks:
if block.key == key:
#only add it to the toybox if its not already in there
if not any(key in l.key for l in toybox.attributes):
toybox.attributes.append(block)
break
注意:
l.key for l in toybox.attributes
是列表解析,并为您提供所有键的列表。
any(key in l.key for l in toybox.attributes)
在该列表中,则 True
会返回key
。