How to determine file, function and line number?

Question:

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

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

How can I do something similar in Python?

Asked By: pengdu

||

Answers:

There is a module named inspect which provides these information.

Example usage:

import inspect

def PrintFrame():
  callerframerecord = inspect.stack()[1]    # 0 represents this line
                                            # 1 represents line at caller
  frame = callerframerecord[0]
  info = inspect.getframeinfo(frame)
  print(info.filename)                      # __FILE__     -> Test.py
  print(info.function)                      # __FUNCTION__ -> Main
  print(info.lineno)                        # __LINE__     -> 13

def Main():
  PrintFrame()                              # for this line

Main()

However, please remember that there is an easier way to obtain the name of the currently executing file:

print(__file__)
Answered By: Tugrul Ates

For example

import inspect
frame = inspect.currentframe()
# __FILE__
fileName  =  frame.f_code.co_filename
# __LINE__
fileNo = frame.f_lineno

There’s more here http://docs.python.org/library/inspect.html

Answered By: Preet Sangha
import inspect
    .
    .
    .
def __LINE__():
    try:
        raise Exception
    except:
        return sys.exc_info()[2].tb_frame.f_back.f_lineno

def __FILE__():
    return inspect.currentframe().f_code.co_filename
    .
    .
    .
print "file: '%s', line: %d" % (__FILE__(), __LINE__())
Answered By: geowar

Building on geowar’s answer:

class __LINE__(object):
    import sys

    def __repr__(self):
        try:
            raise Exception
        except:
            return str(sys.exc_info()[2].tb_frame.f_back.f_lineno)

__LINE__ = __LINE__()

If you normally want to use __LINE__ in e.g. print (or any other time an implicit str() or repr() is taken), the above will allow you to omit the ()s.

(Obvious extension to add a __call__ left as an exercise to the reader.)

Answered By: Matthew

I was also interested in a __LINE__ command in python.
My starting point was https://stackoverflow.com/a/6811020 and I extended it with a metaclass object. With this modification it has the same behavior like in C++.

import inspect

class Meta(type):
    def __repr__(self):
        # Inspiration: https://stackoverflow.com/a/6811020
        callerframerecord = inspect.stack()[1]  # 0 represents this line
        # 1 represents line at caller
        frame = callerframerecord[0]
        info = inspect.getframeinfo(frame)
        # print(info.filename)  # __FILE__     -> Test.py
        # print(info.function)  # __FUNCTION__ -> Main
        # print(info.lineno)  # __LINE__     -> 13
        return str(info.lineno)

class __LINE__(metaclass=Meta):
    pass

print(__LINE__)  # print for example 18
Answered By: Christoph Boeddeker

You can refer my answer:
https://stackoverflow.com/a/45973480/1591700

import sys
print sys._getframe().f_lineno

You can also make lambda function

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
Answered By: Hugh Perkins

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).

Answered By: Elliot G.

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
Answered By: abdullah.cu
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.