Replacing parts of the function code on-the-fly
<p><a href="http://stackoverflow.com/a/12227731/862380">Here</a> I came up with the solution to the other question asked by me on how to remove all costly calling to debug output function scattered over the function code (slowdown was 25 times with using empty function <code>lambda *p: None</code>).</p>

<p>The solution is to edit function code dynamically and prepend all function calls with comment sign <code>#</code>.</p>

<pre><code>from __future__ import print_function

DEBUG = False

def dprint(*args,**kwargs):
    '''Debug print'''
    print(*args,**kwargs)


def debug(on=False,string='dprint'):
    '''Decorator to comment all the lines of the function code starting with string'''
    def helper(f):      
        if not on:
            import inspect
            source = inspect.getsource(f)
            source = source.replace(string, '#'+string) #Beware! Swithces off the whole line after dprint statement
            with open('temp_f.py','w') as file:
                file.write(source)
            from temp_f import f as f_new
            return f_new            
        else:
            return f #return f intact
    return helper


def f():
    dprint('f() started')
    print('Important output')
    dprint('f() ended')

f = debug(DEBUG,'dprint')(f) #If decorator @debug(True) is used above f(), inspect.getsource somehow includes @debug(True) inside the code.

f()
</code></pre>

<p>The problems I see now are these:</p>

<ul>
<li><code>#</code> commets all line to the end; but there may be other statements separated by <code>;</code>. This may be addressed by deleting all <code>pprint</code> calls in <code>f</code>, not commenting, still it may be not that trivial, as there may be nested parantheses.</li>
<li><code>temp_f.py</code> is created, and then new <code>f</code> code is loaded from it. There should be a better way to do this without writing to hard drive. I found <a href="http://code.activestate.com/recipes/550804-create-a-restricted-python-function-from-a-string/" rel="nofollow">this recipe</a>, but haven't managed to make it work.</li>
<li>if decorator is applied with special syntax used <code>@debug</code>, then <code>inspect.getsource</code> includes the line with decorator to the function code. This line can be manually removed from string, but it may lead to bugs if there are more than one decorator applied to <code>f</code>. I solved it with resorting to old-style decorator application <code>f=decorator(f)</code>.</li>
</ul>

<p>What other problems do you see here? </p>

<p>How can all these problems be solved?</p>

<p>What are upsides and downsides of this approach?</p>

<p>What can be improved here?</p>

<p>Is there any better way to do what I try to achieve with this code?</p>

<hr>

<p>I think it's a very interesting and contentious technique to preprocess function code before compilation to byte-code. Strange though that nobody got interested in it. I think the code I gave may have a lot of shaky points.</p>
