Return value of an assignment statement?

Carl Banks pavlovevidence at gmail.com
Fri Feb 22 03:45:59 EST 2008


On Feb 21, 6:52 pm, Steve Holden <st... at holdenweb.com> wrote:
> mrstephengross wrote:
> >> What you can't do (that I really miss) is have a tree of assign-and-test
> >> expressions:
> >>         import re
> >>         pat = re.compile('some pattern')
> >>         if m = pat.match(some_string):
> >>             do_something(m)
>
> > Yep, this is exactly what I am (was) trying to do. Oh well.... Any
> > clever ideas on this front?
>
> The syntax is the way it is precisely to discourage that kind of clever
> idea.

Don't be ridiculous.  Assignment operators are maybe one of the worst
things in existence, but this particular use case (running a sequence
of tests like the above) is perfectly useful and good.

Some Pythonistas will swear to their grave and back that should be
done by factoring out the tests into a list and iterating over it, and
NO OTHER WAY WHATSOEVER, but I don't buy it.  That's a lot of
boilerplate--the very thing Python is normally so good at minimizing--
when it might not be needed.  It would be the right thing for a
complex, pluggable, customizable input filter; but is rarely a better
solution for a simple text processing script.

Quick, at a glance, which code snippet will you understand faster
(pretend you know Perl):


if (/name=(.*)/) {
    $name = chop(\1);
} elsif (/id=(.*)/) {
    $id = chop(\1);
} elsif (/phone=(.*)/) {
    $phone = chop(\1);
}


vs.


def set_phone_number(m):
    phone = m.group(1).strip()

def set_id(m):
    id = m.group(1).strip()

def set_name(m):
    name = m.group(1).strip()

_line_tests = [
    (r"phone=(.*)", set_phone_number),
    (r"name=(.*)", set_name),
    (r"id=(.*)", set_id),
    ]

for pattern,func in _line_tests:
    m = re.match(pattern,line)
    if m:
        func(m)


At this small scale, and probably at much larger scales too, the Perl
example blows the Python example out of the water in terms of
readability.  And that's counting Perl's inherent unreadableness.

If it were a priority, Python could support this set-and-test idiom,
and without an assignment operator.  (Notice Perl doesn't use
assignment operator here.)  For example, a syntax like this (where the
scope of m is local to the if-condition and the body of the if-
statement:

if m where m = re.match(r"name=(.*)",line):
    name = m.group(1).strip()
elif m where m = re.match(r"id=(.*)",line):
    id = m.group(1).strip()
elif m where m = re.match(r"phone=(.*)",line):
    phone = m.group(1).strip()


This won't happen because the set-and-test idiom is relatively minor
and not deemed worthy of syntax support.  But if it were there,
there'd really be nothing clever about it.


Carl Banks



More information about the Python-list mailing list