Разработвам мултиплейър игра. Когато използвам обект от инвентара, той трябва да актуализира статистиката на потребителското създание със стойностите на атрибутите на обект.
Това е моят код:
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
Резюме: Ако модифицирам атрибут директно, ангажиментът работи добре. Вместо това, ако модифицирам атрибут чрез речника на класа, тогава, без значение как го модифицирам след това, той не извършва промени в db.
Някакви идеи?
Благодаря предварително
АКТУАЛИЗАЦИЯ 1:
Освен това това актуализира Health в db, но не и Hunger:
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