namespace/dictionary quandry
Peter Otten
__peter__ at web.de
Wed Sep 22 14:48:13 EDT 2004
Jack Carter wrote:
>> class WeirdNamespace:
>> def __init__(self, d): self.d = d
>> def __getitem__(self, n): return self.d.get(n,repr(n))
>
> So, how and or where does this fit in with my example?
> Does both the call to the function where I want to do
> the eval() and self.push(line) command have to be in the
> same namespace and or file for this to work?
I use a slight variation of Alex' suggestion:
class Locals(dict):
def __getitem__(self, name):
try:
return dict.__getitem__(self, name)
except KeyError:
return name
class CLI(code.InteractiveConsole):
"""Simple test of a Python interpreter augmented with custom
commands."""
commands = { \
"attach" : "DoAttach"
}
def __init__(self, locals = None):
# Call super-class initializer
code.InteractiveConsole.__init__(self, locals, "<console>")
self.locals = Locals(self.locals)
# Compile regular expression for finding commmands
self.regexp = re.compile('[a-z]*')
[The rest of the code is the same as in my previous post]
Now try it:
>>> for name in "abc":
fed to the snake: for name in "abc":
... attach name
fed to the snake: myparse.DoAttach([name])
... attach noname
fed to the snake: myparse.DoAttach([noname])
...
fed to the snake:
DoAttach: ['a']
DoAttach: ['noname']
DoAttach: ['b']
DoAttach: ['noname']
DoAttach: ['c']
DoAttach: ['noname']
Unfortunately this will only work with Python 2.4.
Here's a solution that might work for 2.3:
[Does not require the above modifications]
def process(self, line):
indent = line.lstrip()
# Attempt to match line against our command regular expression
temp_line = string.lstrip(line)
len_1 = len(line)
len_2 = len(temp_line)
white_spaces = len_1-len_2
if white_spaces:
front_padding = line[0:white_spaces]
match = self.regexp.match(temp_line)
if match is not None:
#self.write("process 1\n")
# Extract the command and argument strings
cmd_string = match.group()
arg_string = string.lstrip(temp_line[match.end():])
# Find the function for this command in the command dictionary
function = self.commands.get(cmd_string)
if function is not None:
args = parseArgs(arg_string)
for arg in args:
if arg not in self.locals:
self.locals[arg] = arg
line = makePythonCall("myparse." + function, args)
if white_spaces:
line = front_padding + line
print "fed to the snake:", line
# Return the line to be processed by Python
return line
I just ensure that all arguments not already in self.locals are added with
their name as their value. (I also renamed 'parent' to 'self' - I could not
stand it any longer :-)
Note that I don't particularly like both hacks and would rather use plain
old python functions with standard python syntax instead of your custom
language.
Peter
More information about the Python-list
mailing list