How best to write this if-else?
Andrew Dalke
dalke at acm.org
Sat Apr 21 18:44:33 EDT 2001
Ben Wolfson:
>You could do
>
>def meaningful_name_1(matchobject):
> do_complicated_processing(matchobject.group(1))
>def meaningful_name_2(matchobject): ...etc
>
>re_dispatch = {re.compile(blah):meaningful_name_1,
> re.compile(durh):meaningful_name_2
> ..etc
> }
>for re, func in re_dispatch.items():
...
No, you wouldn't use a dictionary for that since the
order would be undefined, and this sort of situation
often has catch-all regexps which need to go after
the more specific cases. Instead, use a list.
This has the unfortunate overhead of defining a function
for each match. If the dispatch is supposed to modify
variables in the calling function, it isn't very useful.
In addition, one of the things the poster wanted was
the ability to 'return' inside of one of those handlers,
which you cannot do.
There are a couple of other possibilities:
matchers = (
("spam", re.compile("spam")),
("blah", re.compile("blah")),
...
)
def main():
...
name = None
for name, matcher in matchers:
m = matcher.match(line)
if m:
break
if name is None:
raise SystemExit("Game over, man")
if name == "spam":
text1 = m.group(1)
do_complicated_processing (text1)
elif name == "blah":
text1 = m.group(1)
text2 = m.group(2)
print text1, text2
elif ...
This requires using an extra name and making sure there
aren't any typos between the two names - always a problem
but should be caught during testing.
Another approach is to define a new test and store class.
class TestMatch:
def __init__(self):
self.match = None
def __call__(self, pattern, line):
self.match = pattern.match(line)
return self.match
def group(self, g):
return self.match.group(g)
def main():
...
test_match = TestMatch()
if test_match(e1, line):
text1 = test_match.group(1)
do_complicated_processing (text1)
elif test_match(e2, line):
text1 = test_match.group(1)
text2 = test_match.group(2)
print text1, text2
elif test_match(e3, line):
return
This is the closest to what the original poster asked for,
but with the downsides of a more complicated system - using
a function object with side effects - and non-standard Python
code constructs.
So, ahem, "There's More Than One Way To Do It" and what you
choose should be based on what you're comfortable with.
Python isn't going to change to allow assignments in a
conditional expression so you will have to be more verbose.
But there really isn't that much verbosity.
Andrew
dalke at acm.org
More information about the Python-list
mailing list