每次调用python类时创建一个新的python类副本

2024-09-19 23:10:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一些关于如何正确设置我要做的事情的指导。 我有一个名为Attribute Block的类,然后用它创建3或4个属性块对象。如下图所示。。。你知道吗

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中的一个添加到一个对象中,确保在添加时,它是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"),
        ]
    )
]

Tags: 对象keynameselftrue属性defattributes
3条回答

将所有属性块放在一个列表中。你知道吗

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)如果key在该列表中,则返回True。你知道吗

如果要确保添加到ToyBox的属性实例是副本,最简单的方法是使用standard copy module

import copy
...
class ToyBox(object):
    ...
    def add_attribute(self, attribute):
        self.attributes.append(copy.deepcopy(attribute))

如果要自动跟踪所有创建的AttributeBlock对象,可以使用class属性:

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参数允许将其存储在外部dict中。你知道吗

add_attribute_block变成:

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())

使用copy方法在ToyBox中存储未存储在全局容器中的原始对象的副本。你知道吗

相关问题 更多 >