python - How to generate and add an instance method to a class in runtime but compiling a method only once? -


i'm trying implement mixin adds method instance mangles name of base class's specific field name.

code looks this

class timeseriesobjectretrievermixin(object): """time series object retriever mixin.  offers reverse related object retrieval methods mixed in model reverse relation contains time related fields(datefield, datetimefield). """ # todo: serious performance bottleneck due function code compilation every #       instantiation. fix this. def __init__(self, *args, **kwargs):     self._n = {}      time_series_object_name, time_series_field_name in self.time_series:         time_series_object = getattr(self, time_series_object_name)         time_series_field = time_series_object.model._meta.get_field(time_series_field_name)          # time series field has 1 of datefield or datetimefield.         assert(isinstance(time_series_field, datefield) or                isinstance(time_series_field, datetimefield))          self._add_get_in_last_delta(time_series_object_name,                                     time_series_field_name)   def time_series(self):     """     time series property.      must implement property in base class mix     mixin model.      example:             time_seires =             [                 ('reverse_related_object_name', 'created_time'),                 ('votes', 'time'),                 ('cash_flow_rate', 'time'),             ]     """     return super(timeseriesobjectretrievermixin, self).time_series 

so mixin add get_in_last_delta method every instantiated objects.

but causes lot of overhead since compilation processed every object instantiation (_add_get_in_last_delta implemented exec , compile).

is there nice way add runtime generated instance method class in program's first class definition rather class instantiation?


_add_get_in_last_delta() :

def _add_method(self, fn):     types import methodtype     setattr(self, fn, methodtype(self._n[fn], self))  def _add_get_in_last_delta(self,                            time_series_object_name,                            time_series_field_name):     # generate function name.     fn = 'get_{}_in_last_delta'.format(time_series_object_name)      # generate name mangled function code.     exec compile((         'from django.utils import timezone\n'         'def {}(self, delta):\n'         '   return self.{}.filter({}__gte=(timezone.now()-delta))').         format(fn, time_series_object_name, time_series_field_name),         '<string>', 'exec') in self._n      # bind method instance.     self._add_method(fn) 

p.s. i'm trying in django mixin class model.

i don't see need compile code. you're doing in dynamically-defined function can done via normal python.

from django.utils import timezone types import methodtype  def _add_get_in_last_delta(self,                            time_series_object_name,                            time_series_field_name):     # generate function name.     fn = 'get_{}_in_last_delta'.format(time_series_object_name)      def dynamic_method(self, delta, obj=time_series_object_name, field=time_series_field_name):         return getattr(self, time_series_object_name).filter(             **{'{}__gte'.format(time_series_field_name): timezone.now()-delta})      # bind method instance.     setattr(self, fn, methodtype(dynamic_method, self)) 

the function still executed every instantiation, inner func compiled once @ first import. (the object/field names provided via default kwargs, because of way python closures work, can safely ignored calling resulting method.)


Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -