Return value of an assignment statement?

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Wed Feb 27 15:15:10 CET 2008


Jeff Schwab a écrit :
> bruno.desthuilliers at gmail.com 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)
>>>         else if m = pat.match(other_string):
>>>             do_other_thing(m)
>>>         else:
>>>             do_default_thing()
>>
>> What you want is:
>>
>> for astring, afunc in ((some_string, do_something), (other_string,
>> do_other_thing)):
>>     m = pat.match(astring)
>>     if m:
>>         afunc(m)
>>         break
>> else:
>>     do_default_thing()
> 
> That looks like the first realistic alternative I've seen.  I find the 
> flow a little hard to follow, but I think that's mostly just because I'm 
> not accustomed to the syntax.

Possibly. It may also have to do with the fact that - as Carl mentions - 
it's a bit overkill for quite a few cases.

> Your approach fits in my head a little more comfortably if none of the 
> lines are longer than eighty columns, if the for-loop isn't given an 
> else-clause (which still looks to my untrained eye like it should match 
> the preceding if),

It tooks me some times to get used to the for/else construct, but I now 
find it quite elegant. And helpful, in that it warns me that 'falling 
thru' the iteration is expected to be a special case.

> and if the break-statement is replaced with a 
> return-statement:
> 
>     actions = (
>             ('some_string', do_something),
>             ('other_string', do_other_thing))
> 
>     def find_action(pattern):
>         for string, action in actions:
>             m = pattern.match(string)
>             if m:
>                 return action
>         return do_default_thing
 >
>     find_action(re.compile('some pattern'))()

As far as I'm concerned, I wouldn't use a function only because I don't 
yet feel confortable with for/else. And using a more generic version of 
this function may not necessarily help, unless it's really a pattern in 
your code (in which case the reader will quickly become familiar with it).

BTW, if you want a more generic version, here's one:

def find_action(test, choices, default):
     for arg, action in choices:
         result = test(arg)
         if result:
             return result, action
     else:
         return None, default


actions = (
             ('some_string', do_something),
             ('other_string', do_other_thing))
           )

pat = re.compile(some_pattern)
test = lambda s: pat.match(s)
match, action = find_action(test, actions, do_default_thing)
action(match)




More information about the Python-list mailing list