Мне нужен метод в составном классе, чтобы вернуть отображение экземпляра.
class Component:
def __init___(self, a, b):
self.a = a
self.b = b
class Entity:
def __init__(self, component, c, d):
self.component= component
self.c = c
self.d = d
def as_dict(self):
mapping_dict = self.__dict__
mapping_dict['component'] = self.component.__dict__
return mapping_dict
Это решение будет работать только один раз при первом вызове метода as_dict(). Когда он вызывается во второй раз, это не сработает, поскольку self.entity теперь будет обращаться к словарю, и вызов __dict__ по нему вызовет AttributeError.
Так что я придумал не очень эффективное решение;
def as_dict(self):
temp_1 = temp_2 = deepcopy(self)
mapping_dict = temp_1.__dict__
mapping_dict['component'] = temp_2.component.__dict__
return mapping_dict
Это работает, но не так эффективно, потому что я делаю глубокую копию экземпляра каждый раз, когда вызываю функцию.
У меня вопрос: почему, когда я вызываю self.entity.__dict__, entity становится типом dict вместо типа Entity? Какой за этим механизм? А также какова наиболее эффективная реализация для получения сопоставления составного объекта?
Глубокое копирование экземпляра не требуется; все, что вам нужно, это мелкая копия __dict__.






Как упоминает Джонршарп, это:
mapping_dict = self.__dict__
не создает копию self.__dict__ - он только связывает локальное имя mapping_dict с объектом, также связанным с self.__dict__ (вы определенно хотите прочитайте это для получения дополнительной информации об именах / привязках python и т. д.).
Итак, следующая строка:
mapping_dict['component'] = self.component.__dict__
фактически эквивалент:
self.component = self.component.__dict__
что явно не то, что вам нужно.
Простое решение - создать новый дикт из self.__dict__. Поскольку нам это нужно как для Component, так и для Entity, лучшим решением будет вычленить это из класс миксина:
class AsDictMixin(object):
def as_dict(self):
return {
k:(v.as_dict() if isinstance(v, AsDictMixin) else v)
for k, v in self.__dict__.items()
}
class Component(AsDictMixin):
def __init___(self, a, b):
self.a = a
self.b = b
class Entity(AsDictMixin):
def __init__(self, component, c, d):
self.component= component
self.c = c
self.d = d
Обратите внимание, что при этом не будут учитываться вычисляемые атрибуты (свойства и т. д.) В учетной записи, только атрибуты простого экземпляра, но я предполагаю, что это то, что вы хотите.
Спасибо за ваш ответ.
mapping_dict = self.__dict__не создает новый словарь, поэтому следующая строка фактически перезаписывает атрибут экземпляра. Почему бы вам не реализовать, например,Mapping, чтобы вы могли использовать сам объект как словарь?