Я разрабатываю многопользовательскую игру. Когда я использую объект из инвентаря, он должен обновить статистику пользовательского существа значениями атрибутов объекта.
Это мой код:
try:
obj = self._get_obj_by_id(self.query['ObjectID']).first()
# Get user's current creature
cur_creature = self.user.get_current_creature()
# Applying object attributes to user attributes
for attribute in obj.attributes:
cur_creature.__dict__[str(attribute.Name)] += attribute.Value
dbObjs.session.commit()
except (KeyError, AttributeError) as err:
self.query_failed(err)
Теперь по какой-то причине это не фиксирует вещи должным образом, поэтому я попробовал:
cur_creature.Health = 100
logging.warning(cur_creature.Health)
dbObjs.session.commit()
Что работает, но не очень удобно (поскольку мне понадобится большой оператор if для обновления различных характеристик существа)
Итак, я попытался:
cur_creature.__dict__['Health'] = 100
logging.warning(cur_creature.Health)
dbObjs.session.commit()
Я получаю 100
в журналах, но никаких изменений, поэтому я попробовал:
cur_creature.__dict__['Health'] = 100
cur_creature.Health = cur_creature.__dict__['Health']
logging.warning(cur_creature.Health)
dbObjs.session.commit()
В журналах все еще «100», но никаких изменений, поэтому я попробовал:
cur_creature.__dict__['Health'] = 100
cur_creature.Health = 100
logging.warning(cur_creature.Health)
dbObjs.session.commit()
Который по-прежнему пишет 100 в журналах, но не фиксирует изменения в базе данных. Теперь это странно, так как рабочая версия отличается только тем, что у нее есть эта строка сверху:
cur_creature.__dict__['Health'] = 100
Вывод: если я изменяю атрибут напрямую, фиксация работает нормально. Вместо этого, если я изменяю атрибут через словарь класса, то, независимо от того, как я изменяю его впоследствии, он не фиксирует изменения в базе данных.
Любые идеи?
заранее спасибо
ОБНОВЛЕНИЕ 1:
Кроме того, это обновляет здоровье в базе данных, но не голод:
cur_creature.__dict__['Hunger'] = 0
cur_creature.Health = 100
cur_creature.Hunger = 0
logging.warning(cur_creature.Health)
dbObjs.session.commit()
Таким образом, просто доступ к словарю не является проблемой для атрибутов в целом, но изменение атрибута через словарь предотвращает фиксацию изменений в этих атрибутах.
Обновление 2:
В качестве временного исправления я переопределил функцию __set_item__(self)
в классе Creatures
:
def __setitem__(self, key, value):
if key == "Health":
self.Health = value
elif key == "Hunger":
self.Hunger = value
Итак, новый код для «использовать объект»:
try:
obj = self._get_obj_by_id(self.query['ObjectID']).first()
# Get user's current creature
cur_creature = self.user.get_current_creature()
# Applying object attributes to user attributes
for attribute in obj.attributes:
cur_creature[str(attribute.Name)] += attribute.Value
dbObjs.session.commit()
except (KeyError, AttributeError) as err:
self.query_failed(err)
Обновление 3:
Просмотрев предложения в ответах, я остановился на этом решении:
In Creatures
def __setitem__(self, key, value):
if key in self.__dict__:
setattr(self, key, value)
else:
raise KeyError(key)
В другом методе
# Applying object attributes to user attributes
for attribute in obj.attributes:
cur_creature[str(attribute.Name)] += attribute.Value