On Monday, December 12, 2011 3:11:18 PM UTC+8, alex23 wrote: > On Dec 8, 3:09 am, Massi <mass...@msn.com> wrote: > > in my script I have a dictionary whose items are couples in the form > > (string, integer values), say > > > > D = {'a':1, 'b':2, 'c':3} > > > > This dictionary is passed to a function as a parameter, e.g. : > > > > def Sum(D) : > > return D['a']+D['b']+D['c'] > > > > Is there a way to create three variables dynamically inside Sum in > > order to re write the function like this? > > > > def Sum(D) : > > # Here some magic to create a,b,c from D > > return a+b+c > > Okay, here's a possible solution that doesn't rely on exec, but does > use the third-party module byteplay (which I believe limits it to > Python 2.5-2.7) and tries to retain as much as possible your syntax > (with some slight adjustments): > > from byteplay import Code, opmap > > class VariableInjector(dict): > def transmute(self, opcode, arg): > if (opcode == opmap['LOAD_GLOBAL']) and (arg in self): > self._transmuted.append(arg) > return opmap['LOAD_FAST'], arg > return opcode, arg > > def make_locals(self, args): > locals = [] > for arg in args: > locals.append((opmap['LOAD_CONST'], self[arg])) > locals.append((opmap['STORE_FAST'], arg)) > return locals > > def bind_to(self, function): > function.ofunc_code = function.func_code > def _(*args, **kwargs): > self._transmuted = [] > code = Code.from_code(function.ofunc_code) > code.code = [self.transmute(op, arg) for op, arg in > code.code] > code.code = self.make_locals(self._transmuted) + > code.code > function.func_code = code.to_code() > return function(*args, **kwargs) > return _ > > For your example, you'd use it like this: > > >>> def sum(): > ... return a + b + c > ... > >>> def product(): > ... return a * b * c > ... > >>> data = VariableInjector(a=1,b=2,c=3) > >>> sum = data.bind_to(sum) > >>> product = data.bind_to(product) > >>> sum() > 6 > >>> product() > 6 > >>> data > {'a': 1, 'c': 3, 'b': 2} > >>> data['a'] = 100 > >>> sum() > 105 > >>> product() > 600 > > I'm not sure how rigorous this would be in real use but it's passed > the few quick toy cases I've tried it out on. > > Any thanks should go to Michael Foord, as this borrows heavily from > his self-less metaclass example: > http://www.voidspace.org.uk/python/articles/metaclasses.shtml
-- http://mail.python.org/mailman/listinfo/python-list