Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail From: 88888 Dihedral Newsgroups: comp.lang.python Subject: Re: Dynamic variable creation from string Date: Mon, 12 Dec 2011 04:49:10 -0800 (PST) Organization: http://groups.google.com Lines: 88 Message-ID: <24728986.18.1323694150411.JavaMail.geo-discussion-forums@prfc16> References: <28e7a11b-f61b-443b-85b4-adaa6ba5bd21@k5g2000pra.googlegroups.com> Reply-To: comp.lang.python@googlegroups.com NNTP-Posting-Host: 1.168.132.130 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1323694275 12620 127.0.0.1 (12 Dec 2011 12:51:15 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Mon, 12 Dec 2011 12:51:15 +0000 (UTC) In-Reply-To: <28e7a11b-f61b-443b-85b4-adaa6ba5bd21@k5g2000pra.googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=1.168.132.130; posting-account=5JdMBQoAAABHnS4mjpqEzxnmWtgiiVNw User-Agent: G2/1.0 X-Google-Web-Client: true Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:17037 On Monday, December 12, 2011 3:11:18 PM UTC+8, alex23 wrote: > On Dec 8, 3:09=A0am, Massi wrote: > > in my script I have a dictionary whose items are couples in the form > > (string, integer values), say > > > > D =3D {'a':1, 'b':2, 'c':3} > > > > This dictionary is passed to a function as a parameter, e.g. : > > > > def Sum(D) : > > =A0 =A0 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) : > > =A0 =A0 # Here some magic to create a,b,c from D > > =A0 =A0 return a+b+c >=20 > 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): >=20 > from byteplay import Code, opmap >=20 > class VariableInjector(dict): > def transmute(self, opcode, arg): > if (opcode =3D=3D opmap['LOAD_GLOBAL']) and (arg in self): > self._transmuted.append(arg) > return opmap['LOAD_FAST'], arg > return opcode, arg >=20 > def make_locals(self, args): > locals =3D [] > for arg in args: > locals.append((opmap['LOAD_CONST'], self[arg])) > locals.append((opmap['STORE_FAST'], arg)) > return locals >=20 > def bind_to(self, function): > function.ofunc_code =3D function.func_code > def _(*args, **kwargs): > self._transmuted =3D [] > code =3D Code.from_code(function.ofunc_code) > code.code =3D [self.transmute(op, arg) for op, arg in > code.code] > code.code =3D self.make_locals(self._transmuted) + > code.code > function.func_code =3D code.to_code() > return function(*args, **kwargs) > return _ >=20 > For your example, you'd use it like this: >=20 > >>> def sum(): > ... return a + b + c > ... > >>> def product(): > ... return a * b * c > ... > >>> data =3D VariableInjector(a=3D1,b=3D2,c=3D3) > >>> sum =3D data.bind_to(sum) > >>> product =3D data.bind_to(product) > >>> sum() > 6 > >>> product() > 6 > >>> data > {'a': 1, 'c': 3, 'b': 2} > >>> data['a'] =3D 100 > >>> sum() > 105 > >>> product() > 600 >=20 > 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. >=20 > 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 This is the way to write an assembler or=20 to roll out a script language to be included in an app by users.=20