How to do this in Python...

Michael Tiller mtiller at ford.com
Fri Jan 24 15:08:26 EST 2003


"Peter Hansen" <peter at engcorp.com> wrote in message
news:3E31568E.FD9C92B5 at engcorp.com...
> Michael Tiller wrote:
> >
> > I'm puzzled by what seems like a missing piece of functionality in
Python.
> ...
> > In C++, I could write a statement like this:
> >
> > if (match=re.match(pattern, string))
> >   // do something with the match object
> >
> > But I cannot figure out how to do the equivalent thing in Python.  The
idea
> > here is to have an assignment statement within an if statement so that I
> > don't have to call match twice or obfuscate the code.  It seems to me
that
> > my current options are:
> >
> > match = re.match(pattern, string)
> > if match:
> >   // do something with match object
> >
> > -or-
> >
> > if re.match(pattern, string):
> >     match = re.match(pattern, string)
> >
> > The first one seems unnecessarily verbose and the second one is
inefficient.
> > Are there any other options?
>
> Yes, the third option is this: get rid of the urge to do this, and
> the belief that it is a good idea.
>
> Such structures have long been fertile ground for bugs in C and
> its children, and reduce the readability of code.  The "functionality"
> you want is actually a deprecated feature in some companies, where
> assignment-tests like that are outlawed in if/for/while statements.
>
> If you can start to think in this style, your code will become more
> readable and you'll have fewer concerns about "missing" functionality
> in Python.

I want to be clear about something.  I have no particular fondness for
the...

if (a=b) then ...

"feature" in C.  I agree that *THAT SYNTAX* is confusing.  But lets not
throw the baby out with the bathwater just because somebody at AT&T didn't
forsee this confusion 30 years ago.  Many people have argued that it is the
Pythonic Way to separate assignment from comparison and that is fine.  But
lets be clear about the fact that you are giving up more than just a
confusing syntactic construct.  My fragment of code didn't expose the
complete issue.  My main problem is that I wanted to do involved mutually
exclusive cases, e.g.,

if (match=re.match(pattern1,string)):
  // Hey I found something that matches pattern1
elif (match=re.match(pattern2,string)):
  // This matches pattern2
elif (match=re.match(pattern3,string)):
  // This matches pattern3
else:
  // I didn't find a match

Now for those who think that the above code is "obfuscated", I would argue
that this is far worse:

match = re.match(pattern1,string)
found_already=0
if match is not None:
  // I found something that matches pattern1.  Oops, I don't want to
continue checking all
  // the other alternatives so I better set a flag
  found_already=1
match = re.match(pattern2,string)
if not found_already and match is not None:
  // I found something that matches pattern2 but I need to be sure not to
check any other
  // possibilities
  found_already=1
match = re.match(pattern3,string)
if not found_already and match is not None:
  // I found pattern3 and even though there are no more patterns to check, I
still need to set
  // this flag so I can trigger the "else" clause
  found_already=1
if not found_already:
  // I didn't find a match

My thanks go out to those people who mentioned the "holder" idiom (rather
than just throwing up their arms in ideological disgust at the idea of
somebody even suggesting such a construct) since the "holder" idiom was
exactly what I needed because it allows me to use if..elif..else without the
easy to misunderstand syntax of C and C++.

--
Mike







More information about the Python-list mailing list