[Python-Dev] statically nested scopes

barry@wooz.org barry@wooz.org
Thu, 2 Nov 2000 13:20:06 -0500 (EST)

>>>>> "GvR" == Guido van Rossum <guido@python.org> writes:

    >> If we get lexical scoping, there should be a fast (built-in)
    >> way to get at all the accessible names from Python.
    >> I.e. currently I can do d = globals().copy() d.update(locals())
    >> and know that `d' contains a dictionary of available names,
    >> with the right overloading semantics.  (PEP 42 now includes a
    >> feature request to make vars() do this by default.)

    GvR> Note that I just deleted that feature request from PEP 42 --
    GvR> vars() or locals() returns the dictionary containing the
    GvR> variables, and you can't just change the semantics to return
    GvR> a newly copied dictionary (which could be quite expensive
    GvR> too!).

Saw that.  I was just thinking that locals() already does what
vars()-no-args does, so why have two ways to do the same thing?

    GvR> I don't think you need to have a mechanism to find all
    GvR> accessible names; I don't see a common use for that.  It's
    GvR> sufficient to have a mechanism to look up any specific name
    GvR> according to whatever mechanism we decide upon.  This is
    GvR> needed for internal use of course; it can also be useful for
    GvR> e.g. variable substitution mechanisms like the one you
    GvR> recently proposed or Ping's Itmpl.

Ah, something like this then:

-------------------- snip snip --------------------
import sys
from UserDict import UserDict

class NamesDict(UserDict):
    def __init__(self, frame):
        self.__frame = frame

    def __getitem__(self, key):
        if self.data.has_key(key):
            return self.data[key]
        locals = self.__frame.f_locals
        if locals.has_key(key):
            return locals[key]
        globals = self.__frame.f_globals
        if globals.has_key(key):
            return globals[key]
        raise KeyError, key

def _(s):
    try: raise 'oops'
    except: frame = sys.exc_info()[2].tb_frame.f_back
    return s % NamesDict(frame)

theirs = 'theirs'
def give(mine, yours):
    print _('mine=%(mine)s, yours=%(yours)s, theirs=%(theirs)s')
-------------------- snip snip --------------------
Python 2.0 (#128, Oct 18 2000, 04:48:44) 
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import dict
>>> dict.give('mine', 'yours')
mine=mine, yours=yours, theirs=theirs