Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #16783 > unrolled thread

Dynamic variable creation from string

Started byMassi <massi_srb@msn.com>
First post2011-12-07 09:09 -0800
Last post2011-12-13 06:21 -0800
Articles 7 on this page of 27 — 13 participants

Back to article view | Back to comp.lang.python


Contents

  Dynamic variable creation from string Massi <massi_srb@msn.com> - 2011-12-07 09:09 -0800
    Re: Dynamic variable creation from string John Gordon <gordon@panix.com> - 2011-12-07 17:45 +0000
      Re: Dynamic variable creation from string MRAB <python@mrabarnett.plus.com> - 2011-12-07 18:07 +0000
    Re: Dynamic variable creation from string "Waldek M." <wm@localhost.localdomain> - 2011-12-07 18:46 +0100
    Re: Dynamic variable creation from string Chris Angelico <rosuav@gmail.com> - 2011-12-08 04:52 +1100
    Re: Dynamic variable creation from string Terry Reedy <tjreedy@udel.edu> - 2011-12-07 17:59 -0500
    Re: Dynamic variable creation from string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-08 00:03 +0000
      Re: Dynamic variable creation from string Terry Reedy <tjreedy@udel.edu> - 2011-12-07 19:27 -0500
        Re: Dynamic variable creation from string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-08 01:59 +0000
        Re: Dynamic variable creation from string Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2011-12-08 10:54 +0200
          Re: Dynamic variable creation from string Massi <massi_srb@msn.com> - 2011-12-09 01:55 -0800
            Re: Dynamic variable creation from string Peter Otten <__peter__@web.de> - 2011-12-09 12:27 +0100
            Re: Dynamic variable creation from string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-09 11:59 +0000
              Re: Dynamic variable creation from string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-09 12:03 +0000
              Re: Dynamic variable creation from string Chris Angelico <rosuav@gmail.com> - 2011-12-09 23:08 +1100
            Re: Dynamic variable creation from string Ethan Furman <ethan@stoneleaf.us> - 2011-12-09 12:01 -0800
            Re: Dynamic variable creation from string Nobody <nobody@nowhere.com> - 2011-12-11 06:42 +0000
              Re: Dynamic variable creation from string alex23 <wuwei23@gmail.com> - 2011-12-11 19:31 -0800
                Re: Dynamic variable creation from string Ethan Furman <ethan@stoneleaf.us> - 2011-12-11 21:00 -0800
                  Re: Dynamic variable creation from string alex23 <wuwei23@gmail.com> - 2011-12-11 22:50 -0800
      Re: Dynamic variable creation from string Chris Angelico <rosuav@gmail.com> - 2011-12-08 14:13 +1100
    Re: Dynamic variable creation from string alex23 <wuwei23@gmail.com> - 2011-12-11 23:11 -0800
      Re: Dynamic variable creation from string 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-12 04:43 -0800
      Re: Dynamic variable creation from string 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-12 04:49 -0800
        Re: Dynamic variable creation from string alex23 <wuwei23@gmail.com> - 2011-12-12 15:45 -0800
          Re: Dynamic variable creation from string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-13 01:35 +0000
            Re: Dynamic variable creation from string 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-13 06:21 -0800

Page 2 of 2 — ← Prev page 1 [2]


#16798

FromChris Angelico <rosuav@gmail.com>
Date2011-12-08 14:13 +1100
Message-ID<mailman.3390.1323314002.27778.python-list@python.org>
In reply to#16794
On Thu, Dec 8, 2011 at 11:03 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>> It is really important that the scope of a,b,c is limited to the Sum
>> function, they must not exisit outside it or inside any other nested
>> functions.
>
> The second part is impossible, because that is not how Python works.
> Nested functions in Python can always see variables in their enclosing
> scope. If you don't want that behaviour, use another language, or don't
> use nested functions.

To the OP: By "nested functions", did you mean actual nested functions
(those defined inside this function), or simply functions called from
this one?

This is a nested function, as the term is usually taken to mean:

def outer_function():
    a = 1
    def inner_function():
        b = 2
        return a+b
    print(inner_function())  # Prints 3

The inner function has access to all of the outer function's
namespace. But if you meant this:

def function_1():
    b = 2
    return a+b

def function_2():
    a = 1
    print(function_1())

then it's quite the other way around - Python never shares variables
in this way (this would have function_1 assume that 'a' is a global
name, so if it's not, you'll get a run-time NameError).

As Steven says, there's no way in Python to hide variables from an
actual nested function. But if you just mean a function called from
this one, then what you want is the normal behaviour (and if you
actually want to share variables, you pass them as arguments).

ChrisA

[toc] | [prev] | [next] | [standalone]


#17019

Fromalex23 <wuwei23@gmail.com>
Date2011-12-11 23:11 -0800
Message-ID<28e7a11b-f61b-443b-85b4-adaa6ba5bd21@k5g2000pra.googlegroups.com>
In reply to#16783
On Dec 8, 3:09 am, Massi <massi_...@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

[toc] | [prev] | [next] | [standalone]


#17036

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-12 04:43 -0800
Message-ID<21495782.256.1323693800361.JavaMail.geo-discussion-forums@prmw6>
In reply to#17019
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

[toc] | [prev] | [next] | [standalone]


#17037

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-12 04:49 -0800
Message-ID<24728986.18.1323694150411.JavaMail.geo-discussion-forums@prfc16>
In reply to#17019
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

This is the way to write an assembler or 
to roll out a script language to be included in an app
by users. 

[toc] | [prev] | [next] | [standalone]


#17089

Fromalex23 <wuwei23@gmail.com>
Date2011-12-12 15:45 -0800
Message-ID<2b414cd2-0f0a-45bf-b61e-9205704ac03a@u10g2000prl.googlegroups.com>
In reply to#17037
On Dec 12, 10:49 pm, 88888 Dihedral <dihedral88...@googlemail.com>
wrote:
> This is the way to write an assembler or
> to roll out a script language to be included in an app
> by users.

This is a garbage comment that has absolutely nothing to do with the
topic at hand _at all_.

[toc] | [prev] | [next] | [standalone]


#17098

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-12-13 01:35 +0000
Message-ID<4ee6abf8$0$11091$c3e8da3@news.astraweb.com>
In reply to#17089
On Mon, 12 Dec 2011 15:45:06 -0800, alex23 wrote:

> On Dec 12, 10:49 pm, 88888 Dihedral <dihedral88...@googlemail.com>
> wrote:
>> This is the way to write an assembler or to roll out a script language
>> to be included in an app by users.
> 
> This is a garbage comment that has absolutely nothing to do with the
> topic at hand _at all_.

Please stop responding to the bot.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#17138

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-13 06:21 -0800
Message-ID<14074134.993.1323786118117.JavaMail.geo-discussion-forums@pruu5>
In reply to#17098
On Tuesday, December 13, 2011 9:35:52 AM UTC+8, Steven D&#39;Aprano wrote:
> On Mon, 12 Dec 2011 15:45:06 -0800, alex23 wrote:
> 
> > On Dec 12, 10:49 pm, 88888 Dihedral <dihedr...@googlemail.com>
> > wrote:
> >> This is the way to write an assembler or to roll out a script language
> >> to be included in an app by users.
> > 
> > This is a garbage comment that has absolutely nothing to do with the
> > topic at hand _at all_.
> 
> Please stop responding to the bot.
> 
> 
> 
> -- 
> Steven

Do we need to talk aout auto, extern, static in python?
Of course not for an interpreter?

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web