python脚本的文件名和行号


113

如何在python脚本中获取文件名和行号。

正是从异常回溯中获得的文件信息。在这种情况下不会引发异常。

Answers:


161

感谢mcandre,答案是:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)

1
使用此方法是否会对性能产生任何影响(例如,运行时间略微增加或需要更多CPU)?
gsinha 2014年

6
@gsinha:每个函数调用都会影响性能。您必须衡量这种影响是否可以接受。
omikron 2015年

5
因此,如果您喜欢“一行”类型的答案,请使用:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-ijk

1
@LimokPalantaemon它发生在currentframe()被调用时,这意味着您只能简化它getframeinfo(currentframe()).lineno(如果您只关心行号而不是文件名)。参见docs.python.org/2/library/inspect.html#inspect.currentframe
亚伦·米勒

1
@joey,打印语句中是否应该没有括号?
MCG

49

是否使用currentframe().f_back取决于是否使用功能。

直接调用检查:

from inspect import currentframe, getframeinfo

cf = currentframe()
filename = getframeinfo(cf).filename

print "This is line 5, python says line ", cf.f_lineno 
print "The filename is ", filename

调用为您执行此操作的函数:

from inspect import currentframe

def get_linenumber():
    cf = currentframe()
    return cf.f_back.f_lineno

print "This is line 7, python says line ", get_linenumber()

2
加一,用于提供可调用函数的解决方案。非常好!
MikeyE

21

如果在公用文件中使用,则非常方便-打印文件名,行号和呼叫者的功能:

import inspect
def getLineInfo():
    print(inspect.stack()[1][1],":",inspect.stack()[1][2],":",
          inspect.stack()[1][3])

11

档案名称

__file__
# or
sys.argv[0]

线

inspect.currentframe().f_lineno

(不是inspect.currentframe().f_back.f_lineno上面提到的)


NameError: global name '__file__' is not defined在我的Python解释器上:Python 2.7.6 (default, Sep 26 2014, 15:59:23)。见stackoverflow.com/questions/9271464/…–
bgoodr

10

最好也使用sys-

print dir(sys._getframe())
print dir(sys._getframe().f_lineno)
print sys._getframe().f_lineno

输出为:

['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace']
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
14

6

只是为了贡献,

linecachepython中有一个模块,这里有两个链接可以提供帮助。

linecache模块文档
linecache源代码

从某种意义上讲,您可以将整个文件“转储”到其缓存中,并使用class中的linecache.cache数据读取它。

import linecache as allLines
## have in mind that fileName in linecache behaves as any other open statement, you will need a path to a file if file is not in the same directory as script
linesList = allLines.updatechache( fileName ,None)
for i,x in enumerate(lineslist): print(i,x) #prints the line number and content
#or for more info
print(line.cache)
#or you need a specific line
specLine = allLines.getline(fileName,numbOfLine)
#returns a textual line from that number of line

对于其他信息,为了进行错误处理,您可以简单地使用

from sys import exc_info
try:
     raise YourError # or some other error
except Exception:
     print(exc_info() )


3

在Python 3中,您可以在以下方面使用变体:

def Deb(msg = None):
  print(f"Debug {sys._getframe().f_back.f_lineno}: {msg if msg is not None else ''}")

在代码中,您可以使用:

Deb("Some useful information")
Deb()

生产:

123: Some useful information
124:

其中123和124是进行呼叫的线路。


0

dmsg是我在VSCode 1.39.2中在Python 3.7.3中获取行号的方法(这是我的调试消息助记符):

import inspect

def dmsg(text_s):
    print (str(inspect.currentframe().f_back.f_lineno) + '| ' + text_s)

调用显示变量name_s及其值:

name_s = put_code_here
dmsg('name_s: ' + name_s)

输出看起来像这样:

37| name_s: value_of_variable_at_line_37
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.