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?
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__ -> 14 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__) 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
fileNo = frame.f_linenoYou can refer my answer: https://stackoverflow.com/a/45973480/1591700
import sys print sys._getframe().f_lineno You can also make lambda function
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.)
return statement in a trivial (read: always on) try-raise-except triplet?return inspects the exception I just raised, as a method of obtaining the stack. Presumably that isn't the only way, but at least Tugrul Ates seems (slightly) more complicated and requires a less-used import.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 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 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 likeprint(), but better:
- It prints both expressions/variable names and their values.
- It's 40% faster to type.
- Data structures are pretty printed.
- Output is syntax highlighted.
- 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).
def get_frameinfo(framelvl=1): """ return info about the caller line, eg: ``` def my_fn(): print(get_frameinfo()) my_fn() ``` would print something like `{'file': '/tmp/ipykernel_93217/1851559004.py', 'fn': 'my_fn', 'line': 2}` """ f = sys._getframe(framelvl) return dict(file=f.f_code.co_filename, fn=f.f_code.co_name, line=f.f_lineno) i think this one is ideal, as you can easily control which frame it reads, and decide what to do with the output
printfunction in C++.