Open shazoom opened 8 years ago
Here is how I would implement that:
def proxyprofile(func):
try:
func = profile(func)
except NameError:
pass
return func
I think I understand the intended workflow. Import proxyprofile
and mark everything you want to profile, but go back and forth between using kernprof
and just plain running the code (e.g. running the test suite) until you've fixed the problem, then go back and remove the @proxyprofile
s before checking things in. Is that right?
Hi Robert,
yes, your workflow description is appropriate but the use case I have is profiling some sqlalchemy code used in a simulation. I have some simple scripts to load functions into iPython to analyse the results. It’s really not a big deal, removing the @profile stuff but it got annoying. I thought it could be streamlined a bit and, it turns out, it’s quite easy.
Thanks for suggesting a simpler alternative.
Best,
Peter.
On 26 February 2016 at 19:10:52, Robert Kern (notifications@github.com) wrote:
Here is how I would implement that:
def proxyprofile(func): try: func = profile(func) except NameError: pass return func
I think I understand the intended workflow. Import proxyprofile and mark everything you want to profile, but go back and forth between using kernprof and just plain running the code (e.g. running the test suite) until you've fixed the problem, then go back and remove the @proxyprofiles before checking things in. Is that right?
— Reply to this email directly or view it on GitHub.
I just put this at the top of my code:
try:
profile
except NameError:
profile = lambda x: x
Ok, that looks good too but I like the idea of importing a module rather than adding a try block to every file I want to profile.
Before I posted my stab at this I checked to see if profile comes from locals
, globals
or __builtins__
. It comes from __builtins__
but you can’t find it in an interactive shell (python -i -m kernprof -l.
)
After a bit more digging just now I realised you can but only in the script which is being profiled (python -m kernprof -l proxyprofile.py
, for example.) So how about this:
—proxyprofile.py—
import __builtin__
if getattr(__builtin__, 'profile', None) is None:
__builtin__.profile = lambda x: x
It’s obviously based on your last comment me but is only an import now. I suppose it would be more pythonic if it were like this:
—proxyprofile.py—
import __builtin__
try:
__builtin__.profile
except NameError:
__builtin__.profile = lambda x: x
2 comments:
__builtin__
is python2 only, replaced by builtins
in python3__builtin__.profile
would raise AttributeError
hereHere is my try:
try:
import builtins
except ImportError:
import __builtin__ as builtins
try:
builtins.profile
except AttributeError:
builtins.profile = lambda x: x
I use this technique in Python 2. (Add @Nodd's technique to handle Python 2 and 3.) It works smoothly and doesn't generate unresolved reference 'profile'
warnings in PyCharm like try/except does:
import __builtin__
profile = __builtin__.__dict__.get('profile', lambda f: f)
I've found it a bit annoying to comment out the @profile decorations so I wrote a really simple decorator to use instead of profile. Actually, it’s a bit obvious so maybe there is another way to do this already which is better; I just couldn't find it ☺
It took an hour to look up the syntax and get it working so I thought it might be useful. I use another decorator to check if the profile decorator is available. Separating the second profiled_func assignment from its execution is to ensure that NameError exceptions, from func, are still propagated and the try...except block only detects if profile is present.