Using Context Manager for control flow

I am wondering if something like this is possible in python (3.2, if relevant).

with assign_match('(abc)(def)', 'abcdef') as (a, b):
    print(a, b)

Where is the behavior:

  • If the regular expression matches, the regular expression groups are obtained in aandb
    • If there is a mismatch, it will throw an exception
  • if a match None, it just completely circumvents the context

My goal here is basically an extremely concise way of doing contextual behavior.

I tried to make the following context manager:

import re

class assign_match(object):
    def __init__(self, regex, string):
        self.regex = regex
        self.string = string
    def __enter__(self):
        result = re.match(self.regex, self.string)
        if result is None:
            raise ValueError
        else:
            return result.groups()
    def __exit__(self, type, value, traceback):
        print(self, type, value, traceback) #testing purposes. not doing anything here.

with assign_match('(abc)(def)', 'abcdef') as (a, b):
    print(a, b) #prints abc def
with assign_match('(abc)g', 'abcdef') as (a, b): #raises ValueError
    print(a, b)

It really works exactly the same as when the regular expressions match, but as you can see, it throws out ValueErrorif there is no match. Is there a way to get it to “jump” to the exit sequence?

Thank!!

+5
1

! , , . if with.

def assign_match(regex, string):
    match = re.match(regex, string)
    if match is None:
        raise StopIteration
    else:
        yield match.groups()

for a in assign_match('(abc)(def)', 'abcdef'):
    print(a)

, . , . (, , ..)

: . . :

for string in lots_of_strings:
    for a in assign_match('(abc)(def)', string):
        do_my_work()
        continue # breaks out of this for loop instead of the parent
    other_work() # behavior i want to skip if the match is successful

. - , !

EDIT2: , .

from contextlib import contextmanager
import re

@contextmanager
def assign_match(regex, string):
    match = re.match(regex, string)
    if match:
        yield match.groups()

for i in range(3):
    with assign_match('(abc)(def)', 'abcdef') as a:
#    for a in assign_match('(abc)(def)', 'abcdef'):
        print(a)
        continue
    print(i)

- , , .:-) , - !

+4

All Articles