assignment expression peeve

Alex Martelli aleax at aleax.it
Wed Oct 15 03:46:52 EDT 2003


Paul Rubin wrote:

> OK, I want to scan a file for lines matching a certain regexp.  I'd
> like to use an assignment expression, like
> 
>    for line in file:
>       if (g := re.match(pat, line)):
>          croggle(g.group(1))
> 
> Since there are no assignment expressions in Python, I have to use a
> temp var.  That's a little more messy, but bearable:
   ...
> This kind of regexp matching is a common pattern and I keep wanting
> assignment expressions whenever I code it, and end up crocking up some
> silly workaround.

Indeed, this is one case where I have in fact used the pattern I
showed in more generic context in the Cookbook, something like (typing
the code back in from memory):

class Matcher(object):
    def __init__(self, pat, *args):
        self.re = re.compile(pat, *args)
        self.mo = None
    def __nonzero__(self):
        return bool(self.mo)
    def match(self, astr):
        self.mo = self.re.match(astr)
        return self.mo
    def __getattr__(self, name):
        return getattr(self.mo, name)

I'd rather inherit from the match object's type, but _sre doesn't
allow that; this containment + delegation is OK, anyway.

Note that my use is somewhat different from yours -- I prefer to
compile my re's at the start anyway, so what I do here is e.g.

ma1 = Matcher(pat1)
ma2 = Matcher(pat2)
for line in file:
    if ma1.match(line): croggle(ma1.group(1))
    elif ma2.match(line): plakke(ma2.group(2))

i.e., I prefer to keep separate matchers, one per re pattern.
If you prefer to have just one matcher:

ma = Matcher()
for line in file:
    if ma.match(pat1, line): croggle(ma.group(1))
    elif ma.match(pat2, line): plakke(ma.group(2))

that's perhaps even easier to arrange:

class Matcher(object):
    def match(self, repat, astr):
        self.mo = re.match(repat, astr)
        return self.mo
    def __getattr__(self, name):
        return getattr(self.mo, name)

no need for __init__ or __nonzero__ (actually I'm not quite
sure WHY I had __nonzero__ last time I coded this -- maybe I
was also testing the matcher itself, not just the return of its
match method).


Alex





More information about the Python-list mailing list