How to determine file, function and line number?

Viewed 41524

In C++, I can print debug output like this:

printf(
   "FILE: %s, FUNC: %s, LINE: %d, LOG: %s\n",
   __FILE__,
   __FUNCTION__,
   __LINE__,
   logmessage
);

How can I do something similar in Python?

9 Answers

wow, 7 year old question :)

Anyway, taking Tugrul's answer, and writing it as a debug type method, it can look something like:

def debug(message):
    import sys
    import inspect
    callerframerecord = inspect.stack()[1]
    frame = callerframerecord[0]
    info = inspect.getframeinfo(frame)
    print(info.filename, 'func=%s' % info.function, 'line=%s:' % info.lineno, message)

def somefunc():
    debug('inside some func')

debug('this')
debug('is a')
debug('test message')
somefunc()

Output:

/tmp/test2.py func=<module> line=12: this
/tmp/test2.py func=<module> line=13: is a
/tmp/test2.py func=<module> line=14: test message
/tmp/test2.py func=somefunc line=10: inside some func

Here is a tool to answer this old yet new question! I recommend using icecream!

Do you ever use print() or log() to debug your code? Of course, you do. IceCream, or ic for short, makes print debugging a little sweeter.

ic() is like print(), but better:

  1. It prints both expressions/variable names and their values.
  2. It's 40% faster to type.
  3. Data structures are pretty printed.
  4. Output is syntax highlighted.
  5. It optionally includes program context: filename, line number, and parent function.

For example, I created a module icecream_test.py, and put the following code inside it.

from icecream import ic
ic.configureOutput(includeContext=True)
def foo(i):
    return i + 333

ic(foo(123))

Prints

ic| icecream_test.py:6 in <module>- foo(123): 456

To get the line number in Python without importing the whole sys module...

First import the _getframe submodule:

from sys import _getframe

Then call the _getframe function and use its' f_lineno property whenever you want to know the line number:

print(_getframe().f_lineno)  # prints the line number

From the interpreter:

>>> from sys import _getframe
... _getframe().f_lineno  # 2

Word of caution from the official Python Docs:

CPython implementation detail: This function should be used for internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python.

In other words: Only use this code for personal testing / debugging reasons.

See the Official Python Documentation on sys._getframe for more information on the sys module, and the _getframe() function / submodule.

Based on Mohammad Shahid's answer (above).

Related