Safe to modify globals(), or not?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Robert Dodier

    Safe to modify globals(), or not?

    Hello,

    I'm interested in introducing new variables into the environment
    of a Python interpreter or program.

    In reading through old posts to this newsgroup, I see there is
    an often-repeating warning against modifying the contents of locals().
    Fair enough. However, is there anything wrong with modifying globals()
    ?

    In the list of built-in functions
    (http://www.python.org/doc/lib/built-in-funcs.html)
    locals() has an explicit warning, globals() doesn't. Does that mean
    it's safe to modify globals() ?

    By the way, is there another way to introduce a new variable into
    a scope (local or global) other than assigning directly to the
    dictionary returned by locals() or globals() ?

    Just some context -- I want to parse strings written in a
    "little language" and then have new variables show up in the Python
    environment so the user can manipulate them. E.g.,
    [color=blue][color=green][color=darkred]
    >>> parse_funky_lan guage("Hey, this is far out, man.")
    >>> Hey.part_of_spe ech[/color][/color][/color]
    Interjection

    Any light you can shed on this issue will be appreciated.
    Thanks for not getting distracted about whether this is useful.

    regards,
    Robert Dodier
    --
    If I have not seen as far as others, it is because
    giants were standing on my shoulders. -- Hal Abelson
  • Aahz

    #2
    Re: Safe to modify globals(), or not?

    In article <6714766d.04012 91559.45413e0d@ posting.google. com>,
    Robert Dodier <robert_dodier@ yahoo.com> wrote:[color=blue]
    >
    >In reading through old posts to this newsgroup, I see there is
    >an often-repeating warning against modifying the contents of locals().
    >Fair enough. However, is there anything wrong with modifying globals()
    >?[/color]

    Not wrong, exactly, but there may well be in the future, and there are
    better ways currently.
    [color=blue]
    >By the way, is there another way to introduce a new variable into
    >a scope (local or global) other than assigning directly to the
    >dictionary returned by locals() or globals() ?[/color]

    For locals, it's a lot trickier, but you're less likely to want to do
    that.
    [color=blue]
    >Just some context -- I want to parse strings written in a
    >"little language" and then have new variables show up in the Python
    >environment so the user can manipulate them. E.g.,
    >[color=green][color=darkred]
    > >>> parse_funky_lan guage("Hey, this is far out, man.")
    > >>> Hey.part_of_spe ech[/color][/color]
    > Interjection[/color]

    import __main__
    tmp = parse_funky_lan guage("Hey, this is far out, man.")
    setattr(__main_ _, tmp.name, tmp.value)

    In the context of the interactive interpreter, it's a bit harder to do;
    I don't remember off-hand what the namespace of the interpreter is.
    --
    Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

    "The joy of coding Python should be in seeing short, concise, readable
    classes that express a lot of action in a small amount of clear code --
    not in reams of trivial code that bores the reader to death." --GvR

    Comment

    • Terry Reedy

      #3
      Re: Safe to modify globals(), or not?


      "Robert Dodier" <robert_dodier@ yahoo.com> wrote in message
      news:6714766d.0 401291559.45413 e0d@posting.goo gle.com...[color=blue]
      > Hello,
      >
      > I'm interested in introducing new variables into the environment
      > of a Python interpreter or program.[/color]

      This is a bit vague and not obviously connected to your question. Let's
      ignore this.
      Globals() returns the module-specific 'global' namespace, as opposed to the
      function-local namespace.
      [color=blue]
      > In reading through old posts to this newsgroup, I see there is
      > an often-repeating warning against modifying the contents of locals().[/color]

      Outside of functions, locals() == globals(). Inside of functions, where
      locals() != globals() and is therefore not redundant and potentially
      useful, the result is only guaranteed to be a read-only *copy* of the
      current state of the local namespace. Even if it is writable, the changes
      may only change the *copy* and not the local namespace itself. This makes
      for subtle bugs when the programmer expects (if falsely) that changes are
      propagated.
      [color=blue]
      > Fair enough. However, is there anything wrong with modifying globals()[/color]

      No. "globals()['a'] = 3" is exactly the same as "a=3" executed at module
      scope, outside of functions. The purpose is to allow you to set a variable
      whose name you do not know until runtime. An example, as in your
      application, is when the name comes from user input.

      Having said that, you do need to ask yourself whether you really want to
      put user variables in the global namespace that your are using yourself for
      your code, which will wreck havoc when there is a name collision. Or
      whether you should put them is a separate namespace dict such as uservars.
      And then exec user code with uservars as the globals. Or something like
      that.

      Terry J. Reedy




      Comment

      • Peter Otten

        #4
        Re: Safe to modify globals(), or not?

        Aahz wrote:
        [color=blue]
        > import __main__
        > tmp = parse_funky_lan guage("Hey, this is far out, man.")
        > setattr(__main_ _, tmp.name, tmp.value)
        >
        > In the context of the interactive interpreter, it's a bit harder to do;
        > I don't remember off-hand what the namespace of the interpreter is.[/color]

        You don't need to :-)

        Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
        [GCC 3.2] on linux2
        Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
        >>> __name__[/color][/color][/color]
        '__main__'

        Peter

        Comment

        Working...