how to acces the block inside of a context manager as sourcecode

Aaron Brady castironpi at gmail.com
Wed Nov 19 19:01:16 EST 2008


See below.

On Nov 19, 8:02 am, Daniel <inva... at invalid.invalid> wrote:
> Hi Aaron,
>
> let me give you the reason for the context manager:
> I am driving handware with a python script, basically a data acquisition
> program which looks like this:
>
> with dataStore('measurement1.dat') as d:
>         magnet.setField(0)
>         r1=doExperiment(voltage=0.345, current=0.346, temperature=33)
>         magnet.setField(1)
>         r2=doExperiment(voltage=0.32423, current=0.3654, temperature=45)
>         d.append(r2-r1)
>
> the script does the measuring and the context manager stores the result
> (r1 and r2), at the end the result is printed.
>
> The source code serves as the documentation (it contains many parameters
> that need to be well documented), so I print the source code, cut it out
> and glue it into my lab notebook.
> Now I want to automate this process, i.e. the dataStore should print the
> sourcecode.
>
> Daniel
>
> > There isn't a solution in the general case, because strings can be
> > executed.  However, 'inspect.currentframe()' and
> > 'inspect.getsourcelines(object)' can handle some cases, and your idea
> > is (I believe) how getsourcelines works itself.  You can probably do
> > it without a context manager, e.g. 'print_next_lines( 5 )' or
> > 'print_prior_lines( 2 )', dedenting as needed.
>
>

Hi.  It is not the role of a 'dataStore' object in your object model,
which is why, ideally, you would separate those two functions.
However, if 'dataStore' always needs the printing functionality, you
could built it in for practical reasons.  That has the benefit that
you don't need to specify, such as 'print_next_lines( 5 )', how many
lines to print, since the context manager can count for you, and if
you add a line, you won't need to change to 'print_next_lines( 6 )'.
Lastly, you could use two con. managers, such as:

with printing:
  with dataStore('measurement1.dat') as d:
    magnet.setField(0)

You may or may not find that relevant.

Here is some code and output:

import inspect
class CM( object ):
    def __enter__(self):
        self.startline= inspect.stack( )[ 1 ][ 0 ].f_lineno
    def __exit__(self, exc_type, exc_value, traceback):
        endline= inspect.stack( )[ 1 ][ 0 ].f_lineno
        print self.startline, endline

with CM(): #line 9
    a= 0
    b= 1
    c= 2

with CM(): #line 14
    d= 3
    e= 4

/Output:

9 12
14 16



More information about the Python-list mailing list