Profiling from *within* a module

David Boddie davidb at mcs.st-and.ac.uk
Tue Oct 7 21:06:58 EDT 2003


Leo Breebaart <leo at lspace.org> wrote in message news:<blugef$dk5$1 at news.tudelft.nl>...

> Given the file 'leotest.py':
> 
> ---------------------------------------------------------------------------
> """ leotest.py - test ways of profiling python functions. """
> 
> def foo():
>     pass
> 
> def test():
>     for i in range(10000): foo()
> 
> def myprofile():
>     import profile
>     profile.run('test()')
> 
> if __name__ == "__main__":
>     myprofile()
> ---------------------------------------------------------------------------

Fine so far.

[...]

[Using the interpreter interactively...]

>   >>> leotest.myprofile()
>   Traceback (most recent call last):
>     File "<stdin>", line 1, in ?
>     File "leotest.py", line 11, in myprofile
>       profile.run('test()')
>     File "/usr/lib/python2.3/profile.py", line 71, in run
>       prof = prof.run(statement)

The following two lines of code indicate what's happening:

>     File "/usr/lib/python2.3/profile.py", line 403, in run
>       return self.runctx(cmd, dict, dict)
>     File "/usr/lib/python2.3/profile.py", line 409, in runctx
>       exec cmd in globals, locals
>     File "<string>", line 1, in ?
>   NameError: name 'test' is not defined

Looking at the profile.py file, it seems that the profiler executes the command
you give in the __main__ namespace. To get around this, you need to use the
Profile class directly:

def myprofile():
    import profile
    
    # Create a profiler instance.
    p = profile.Profile()
    
    # Retrieve a dictionary corresponding to the modules namespace.
    dict = globals()
    
    # Profile the test function and print the statistics.
    p.runctx('test()', dict, dict)
    p.print_stats()

This should work from either the command line or within an interactive session.
There may be a cleaner way to do the above if there's a convenience function
like profile.run which takes global and local attribute dictionaries.

> I think I'm simply misunderstanding how modules and functions and scopes
> interact in Python, but I can't discover where exactly I'm going wrong
> -- and I can't find a workaround either.

I think you do understand how the scopes interact. It's just that the profile.run
function is playing tricks behind your back. ;-)

David




More information about the Python-list mailing list