13

A useful print for debugging in C++ is

std::cout << __LINE__ << std::endl;

Of course you can simply print a string with the line number, for example:

std::cout << "this is line 54" << std::endl;

but it won't keep changing the line number when you move it around. Is there any equivalent macro in Python?

L. F.
  • 19,445
  • 8
  • 48
  • 82
A. Fenzry
  • 414
  • 3
  • 12
  • 3
    Possible duplicate of [filename and line number of python script](https://stackoverflow.com/questions/3056048/filename-and-line-number-of-python-script) – rkersh Jun 25 '19 at 21:54
  • @rkersh you are right, however I think the answer here is the best one, so not sure how to proceed in this case (I feel closing the question removes valuable knowledge). Maybe the the user from the accepted answer could reply on the other question and then I can suppress this one – A. Fenzry Jun 26 '19 at 01:40

4 Answers4

11

No macro, but you can do

from inspect import currentframe, getframeinfo

print(getframeinfo(currentframe()).lineno)

To get the current line number in Python.

The "current line number" will be the line where currentframe() is evaluated, FYI.

CoffeeTableEspresso
  • 2,614
  • 1
  • 12
  • 30
10

As a function, so you don't have to expand it everywhere

import sys

def LINE():
    return sys._getframe(1).f_lineno


print('This is line', LINE())

TBH I've never understood the point of the inspect module at all.

o11c
  • 15,265
  • 4
  • 50
  • 75
  • 7
    The inspect module is meant to be public ways of accessing information about Python objects in a portal manner, say, for example, if you need a Python implementation other than CPython (say, PyPi, Jython or IronPython). You should not use `_getframe`, explicitly, "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." If you use inspect, you can guarantee it works on more than just CPython. Using `getframeinfo(currentframe())` works everywhere, `_getframe` may break. – Alex Huszagh Jun 25 '19 at 22:02
4

Define a class with the __str__ method returns the current line number:

import inspect

class LineNo:
    def __str__(self):
        return str(inspect.currentframe().f_back.f_lineno)


__line__ = LineNo()

Now it's more similar to C++:

print(__file__, __line__)
Elyar Adil
  • 41
  • 1
2

I found this solution the shortest, which seems to be not implementation specific:

import inspect
def __LINE__(): return inspect.stack()[1].lineno

For some reason I like to use stack as it returns a list. If I need to go deeper then I use stack()[<n>].frame.

UPDATE I have checked the performance! sys._getframe(1).f_lineno or inspect.currentframe().f_back is much faster! Instead of calling my __LINE__() I put directly the _getframe(1) solution. If called 1e6 times, the gain is over 10 minutes!

UPDATE2 I think I have found an even faster way. If performance does count and the __LINE__ is used inside a single module, then this can be used:

import inspect
__LINE__ = inspect.currentframe()
print(__LINE__.f_lineno)
print(__LINE__.f_lineno)

It prints (a little bit unexpectedly):

3
4
TrueY
  • 7,360
  • 1
  • 41
  • 46
  • if you are unfortunate enough to be running python <3.5, you want: `return inspect.stack()[1][2]`, as the frame isnt a named tuple until 3.5. – Kaia Aug 18 '22 at 18:28