Override Attribute Access Precedence Having A Data Descriptor
I have a bunch of instances of a MongoEngine model. And the profiler shows that a lot of time is spent in __get__ method of MongoEngine model fields: ncalls tottime percall c
Solution 1:
Here is my solution which seems to work:
def_mock_me_instance(self, obj):
"""Patch a MongoEngine model instance to not use descriptors
to access field values.
"""# copy class
Model = type(obj.__class__.__name__, obj.__class__.__bases__,
dict(obj.__class__.__dict__))
# add the original model to the base classes, so that isinstance() can work
Model.__bases__ = (self.__class__,) + Model.__bases__
# replace descriptor so that values from __dict__ can be seenfor field_name in obj._fields:
setattr(Model, field_name, None)
obj.__dict__.update(obj.__dict__['_data'])
obj.__class__ = Model # replace the classreturn obj
How it works
- I create a copy of the class whose instance the object is.
- Put the original model in the base classes, so that
isinstance
andissubclass
can work. - I copy the data into the object's
__dict__
. The values are ignored for now, because we have data descriptors with the same name which override access to the data. - I assign
None
to the descriptors in the class (MongoEngine model fields in my case).None
is not a descriptor, so values from__dict__
of the object are seen now. - I replace object's class
The speed gain is ~600% (was 17 seconds, now it's 3).
Post a Comment for "Override Attribute Access Precedence Having A Data Descriptor"