Regular expression question
walt
whrauser at erols.com
Sun Nov 24 11:28:53 EST 2002
One small change:
jepler at unpythonic.net wrote:
> You're doing a number of "unpythonic" things in this code. It's best to
> learn to speak Python like a native, to get beyond building up a "phrasebook"
> to translate Perl statements into Python statements.
>
> The biggest "unpythonic" thing is referring to an arbitrary global
> variable by its name at runtime. This is very bad, since it lets a
> user refer to any function. Besides that, you'll probably encapsulate
> the Python version in a module (since it's longer than a line or two),
> but the Python "globals()" returns the globals of the current module,
> not the calling module.
>
> Anyway, here's an attempt at a Pythonic version of the perl code you
> posted. Yes, it's longer than the Perl version. To use it, you'd write
>
> def f(s): return s.upper()
> def g(s): return s.title()
> function_map = {'f': f, 'g': g}
> print substitute_template("The lessons are: '%%f%%' and '%%g%%'",
> function_map, "python is not perl")
> # Test out error handling
> print substitute_template("At the tone, time time is 10PM: %%z%%",
> function_map, "")
>
> (The third argument corresponds to $variable in your example)
>
> Here's the code to implement the 'substitute_template' function:
> import re
>
> # Since python wouldn't just refer to a global 'variable', a Subfunc
> # class records the desired argument and the function map for later use.
> # You can call a Subfunc instance just like it was a plain function
> class Subfunc:
> def __init__(self, function_map, arg):
> self.function_map = function_map
> self.arg = arg
>
> def __call__(self, s):
> fname = s.group(1).lower()
> # Error handling should probably be more sophisticated.
> # But hell, it's better than terminating the whole program...
> try:
> f = function_map[s]
> except KeyError:
> return "*** ERROR: bad substitution %r ***" % fname
> return f(self.arg)
>
> # Compile the regular expression, since we expect to be matching it frequently
> subre = re.compile("%%(.?)%%")
>
> # Here's the function you call. It creates a Subfunc instance and passes
> # it on to re.sub
> def substitute_template(template, function_map, arg):
> return subre.sub(Subfunc(function_map, arg), template)
>
> Enhancing the code to let $variable be an arbitrary parameter list
> is fairly easy. You'll need to learn about *args (and maybe **kw)
> parameters, and either the f(*args, *kw) calling convention or the
> apply function.
>
> Jeff
More information about the Python-list
mailing list