hr0m hr0m - 5 months ago 16
Python Question

Hide post-function calls in with statement

I have a function

f
that returns two parameters. After this function, I use the first parameter. I need the second one to glue things together with another function
g
. So my code would look like:

a, b = f()
# do stuff with a
g(b)


This is very repetitive, so I figured I could use something like a RAII approach. But, since I don't know when objects will die and my main goal is to get rid of the repetitive code, I used the
with
statement:

with F() as a:
# do stuff with a


That's it. I basically created an object
F
around this function, supplying
__enter__
and
__exit__
functions (and obviously
__init__
function).

However, I still wonder whether this is the right "Pythonic" way to handle this, since a
with
statement was meant to handle exceptions. Especially this
__exit__
function has three arguments, which I don't use at the moment.

Edit (further explanations):
Whenever i call
f()
i NEED to do something with
b
. It does not matter what happened in between. I expressed it as
g(b)
. And exactly this i hide away in the with statement. So the programmer doesn't have to type
g(b)
again and again after every call of
f()
, which might get very messy and confusing, since
#do stuff with a
might get lengthy.

Answer

A slightly more pythonic way of doing it would be to use the contextlib module. You can do away with rolling out your own class with __enter__ and __exit__ functions.

from contextlib import contextmanager

def g(x):
    print "printing g(..):", x

def f():
    return "CORE", "extra"

@contextmanager
def wrap():
    a, b = f()
    try:
        yield a
    except Exception as e:
        print "Exception occurred", e
    finally:
        g(b)
if __name__ == '__main__':
    with wrap() as x:
        print "printing f(..):", x
        raise Exception()

Output:

$ python temp.py
printing f(..): CORE
Exception occurred
printing g(..): extra