I am developing a multiplayer game. When I use an object from inventory, it should update the user creature\'s stats with the values of the attributes of an object.
Don't use __dict__
. Use getattr
and setattr
to modify attributes by name:
for attribute in obj.attributes:
setattr(cur_creature,str(attribute.Name), getattr(cur_creature,str(attribute.Name)) + attribute.Value)
More info:
setattr
getattr
The problem does not reside in SQLAlchemy but is due to Python's descriptors mechanism. Every Column
attribute is a descriptor: this is how SQLAlchemy 'hooks' the attribute retrieval and modification to produce database requests.
Let's try with a simpler example:
class Desc(object):
def __get__(self, obj, type=None):
print '__get__'
def __set__(self, obj, value):
print '__set__'
class A(object):
desc = Desc()
a = A()
a.desc # prints '__get__'
a.desc = 2 # prints '__set__'
However, if you go through a
instance dictionary and set another value for 'desc'
, you bypass the descriptor protocol (see Invoking Descriptors):
a.__dict__['desc'] = 0 # Does not print anything !
Here, we just created a new instance attribute called 'desc'
with a value of 0. The Desc.__set__
method was never called, and in your case SQLAlchemy wouldn't get a chance to 'catch' the assignment.
The solution is to use setattr, which is exactly equivalent to writing a.desc
:
setattr(a, 'desc', 1) # Prints '__set__'