[Python-ideas] if with as

Sam free.condiments at gmail.com
Wed Mar 7 20:59:58 CET 2007


On 04/03/07, Scott Dial <scott+python-ideas at scottdial.com> wrote:
> As for this particular case, it is only useful in a very restricted set
> of expressions and I was only able to find a handful of cases in stdlib
> where I could drop in a "if x as y". I believe this is an indication of
> how rarely one wants to do this. YMMV.

I have a concrete use case. My hobby MUD server needs to do a lot of
parsing of players' input, as you'd expect. I use pyparsing to
construct the grammar, but I then have the slightly hairy problem of
dispatching to the correct method. Let's consider a single command,
'target', where the rest of the line can take one of three valid
forms: 'set $name to word list here', 'clear $name', and 'list'.
Presently, the code looks like this (minus some permission-checking
complications and room sanity checks):

def targetDistributor(actor, text):
    try:
        name, target = target_set_pattern.parseString(text)
    except ParseException:
        pass
    else:
        targetSet(actor, name.lower(), target)
        return
    try:
        name, = target_clear_pattern.parseString(text)
    except ParseException:
        pass
    else:
        targetClear(actor, name.lower())
        return
    try:
        target_list_pattern.parseString(text)
    except ParseException:
        pass
    else:
        targetList(actor)
        return
    badSyntax(actor)

Yuck. But, let's rewrite this using as-syntax and two new functions:

#for patterns which return no useful results, but just need to match
(whose results, when bool-ified, result in False)
def matchnoresults(pattern, string):
    try:
        pattern.parseString(string)
    except ParseException:
        return False
    return True

def matchwithresults(pattern, string):
    try:
        res = pattern.parseString(string)
    except ParseException:
        return False
    return res

def targetDistributor(actor, rest, info):
    if matchwithresults(target_set_pattern, rest) as name, target:
        targetSet(actor, name, target)
    elif matchwithresults(target_clear_pattern, rest) as name,:
        targetClear(actor, name)
    elif matchnoresults(target_list_pattern, rest):
        targetList(actor)
    else:
        badSyntax(actor)

I do think that the majority of use cases will be parsing, or in
similar cases where one needs to both test for success and obtain
results from the test.



More information about the Python-ideas mailing list