Regular expression question

walt whrauser at erols.com
Sun Nov 24 11:32:44 EST 2002


Sorry, hit the wrong key.

One small correction to this section:

                fname = s.group(1).lower()
                try:
                    f = function_map[fname]     # was [s],  s is match object.
                except KeyError:

Walt

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