I was sitting around and a thought crossed my mind, "How can I get the function name of a function that the trace is in?". I thought about it for a few minutes, and said to myself, "The stack must know". But how do I read the function names of the stack in Python??
For all these system level hacks, usually the sys module has something to offer, and this case was no exception. Here's how you can do it (using something called a "frame object"):
print sys._getframe().f_code.co_name
Another useful modification of the snippet above can give us the name of the function that is calling the current function. This is how it looks:
print sys._getframe(1).f_code.co_name
So as you saw, the argument of sys._getFrame() can take you up or down the stack as your need may be. This utility of the sys module is extremely useful while logging for errors. Almost every good programmer uses some kind of logging in his code. So far most of my logging was using independant file writes or console writes. With my newfound knowledge, all that was going to change, so I wrote myself a small, yet handy logger for my forthcoming projects. Here's the script.
I integrated this into one of the apps I was making and well, it was simply fantastic. Now I just piped out the log messages to this module and it would automatically determine which function was sending the messages. I wrote an app with a GUI in PyQt4, and as will all GUI apps, tracking events of widgets is extremely important in figuring out what went wrong during debugging. This is what the output of my new logger looked like:
Tue Jul 20 12:32:53 2010: <loadAppData()> Trying to load application dataTue Jul 20 12:32:53 2010: <loadAppData()> Values picked up from appdata file. Interval:43; Dirs:[]Tue Jul 20 12:32:53 2010: <loadAppData()> Application data loaded successfullyTue Jul 20 12:32:56 2010: <btnAdd_Click()> Add button clickedTue Jul 20 12:33:12 2010: <saveAppData()> Trying to save application dataTue Jul 20 12:33:12 2010: <saveAppData()> Application data saved successfully!Tue Jul 20 12:33:26 2010: <trayIcon_Click()> Tray icon clicked. Current visible status:TrueTue Jul 20 12:33:26 2010: <trayIcon_Click()> Tray icon event complete. Current visible status:FalseTue Jul 20 12:33:30 2010: <trayIcon_Click()> Tray icon clicked. Current visible status:FalseTue Jul 20 12:33:30 2010: <trayIcon_Click()> Tray icon event complete. Current visible status:TrueTue Jul 20 12:33:35 2010: <closeEvent()> Form close event raisedTue Jul 20 12:33:35 2010: <saveAppData()> Trying to save application dataTue Jul 20 12:33:35 2010: <saveAppData()> Application data saved successfully!Tue Jul 20 12:33:35 2010: <closeEvent()> Program is exiting.
This is so neat :D
Excellent post! I have only very recently found your blog. I am a student just being introduced to Python programming. I came across your blog from a forum that you participate in. I have been very impressed with your presentation of material here! I am becoming a regular reader!
ReplyDeleteNice to know that my exploits are proving to be useful. Where are you from? Feel free to mail me if you ever need any kind of guidance.
ReplyDeleteI am from north Alabama. I am an ex-component level repair technician, now a student at ITT Tech. Python is the first programming course I have ever taken (I had only built some simple batch files prior to this).
ReplyDeleteThanks for the offer of individual help by e-mail, I hope to not need to worry you so. Although I have of course struggled with some of the challenges I have been assigned, so far I have only asked for suggestions twice by the net to some forums I have signed on to.