How to determine file, function and line number?

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

Method 2

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

Method 3

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

Method 4

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

import sys
print sys._getframe().f_lineno

You can also make lambda function

Method 5

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

Method 6

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

Method 7

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__())

Method 8

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

Method 9

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x