@millioner1488
Ветеран IT

Как исправить повторение одного и того же экземпляра в списке?

Всем доброго дня!

Пишу плагин для Blender, чтобы импортировать модельки из одной игрульки в редактор. Есть проблема при чтении данных моделей, когда считываю вложенные модели и добавляю их в список, то все данные списка (visuals или meshes) заменяются данными последнего прочитанного экземпляра.

Вот сам код:

class Model:
    meshes: List[Mesh] = None
    visuals: List[ModelStd] = None
    model_skeleton: ModelSkeleton = None

    def __init__(self):
        self.meshes = []
        self.visuals = []
        self.model_skeleton = ModelSkeleton()

    def read(self, reader: MetroReader):
        header = self._read_header(reader)

        if not header:
            return

        m_type = header.get_type()
        reader.offset = 0

        if m_type == ModelType.Std:
            std = ModelStd()
            std.read(reader)

            self.visuals.append(std)

        if m_type == ModelType.Skin:
            mesh = Mesh()
            mesh.read(reader)

            self.meshes.append(mesh)

        if m_type == ModelType.Skeleton or m_type == ModelType.Skeleton2 or m_type == ModelType.Skeleton3:
            self.model_skeleton.read(reader)

        if m_type == ModelType.Hierarchy or m_type == ModelType.Hierarchy_Skinned:
            self._read_hierarchy(reader)

    def _read_header(self, reader: MetroReader):
        header = None

        while reader.more():
            chunk = Chunk()
            chunk.read(reader)

            if chunk.id == ModelChunkType.HeaderChunk.value:
                header = ModelHeader()
                header.read(chunk.reader)

                break

        return header

    def _read_hierarchy(self, reader: MetroReader):
        children = None

        while reader.more():
            chunk = Chunk()
            chunk.read(reader)

            if chunk.id == ModelChunkType.ChildrenChunk.value:
                children = chunk

                break

        if not children:
            return

        reader = children.reader

        while reader.more():
            child = Chunk()
            child.read(reader)

            self.read(child.reader)



Cтруктура ModelStd:

@dataclasses.dataclass
class ModelStd(ModelBase):
    vertex: ModelVertex = ModelVertex()
    faces: ModelFaces = ModelFaces()

    def read(self, reader: MetroReader):
        while reader.more():
            chunk = Chunk()
            chunk.read(reader)

            if chunk.id == ModelChunkType.HeaderChunk.value:
                self.header = ModelHeader()
                self.header.read(chunk.reader)

            if chunk.id == ModelChunkType.MaterialsChunk.value:
                self.material = ModelMaterial()
                self.material.read(chunk.reader, self.header)

            if chunk.id == ModelChunkType.VerticesChunk.value:
                self.vertex.read(chunk.reader, self.header)

            if chunk.id == ModelChunkType.FacesChunk.value:
                self.faces.read(chunk.reader, self.header)



P.S. Может проблема в рекурсии?
P.S.S. Сами данные в std всегда разные, но после чтения все элемента списка заменяются на данные последнего экземпляра. Допустим, мы прочитали ModelStd_01 и добавили в список, потом ModelStd_02, ModelStd_03 и далее, но в списке взамен 3-х разных элементов будет [ModelStd_03, ModelStd_03, ModelStd_03], а должно быть [ModelStd_01, ModelStd_02, ModelStd_03]. Почему так и как это исправить?
  • Вопрос задан
  • 94 просмотра
Решения вопроса 1
Валерий Жмышенко
первое что стоит сделать и проверить добавить @dataclass в базовую модель, что б генерировался метод init и атрибуты перестали быть общими
и второе что скорее всего поможет это использовать field для создания экземпляров
вместо
vertex: ModelVertex = ModelVertex()

писать как в документации

vertex: ModelVertex = field(default_factory=ModelVertex)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы