Python 脚本的文件名和行号

如何在 Python 脚本中获得文件名和行号?

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

156173 次浏览

多亏了 mcandre 答案是:

#python3
from inspect import currentframe, getframeinfo


frameinfo = getframeinfo(currentframe())


print(frameinfo.filename, frameinfo.lineno)

文件名 :

__file__
# or
sys.argv[0]

线 :

inspect.currentframe().f_lineno

(不包括上述 inspect.currentframe().f_back.f_lineno)

是否使用 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()
import inspect


file_name = __FILE__
current_line_no = inspect.stack()[0][2]
current_function_name = inspect.stack()[0][3]


#Try printing inspect.stack() you can see current stack and pick whatever you want

只是为了帮忙,

在 python 中有一个 linecache模块,这里有两个链接可以帮助。

Linecache 模块文档
Linecache 源代码 linecache 源代码

在某种意义上,您可以将整个文件“转储”到其缓存中,并使用 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() )

如果在普通文件中使用,打印文件名、行号和调用者的函数非常方便:

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

最好也使用 sys-

import 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

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

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

在 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是打电话的线路。

戈兰风格

import inspect
import sys
import atexit


ERR_FILE = open('errors.log', 'w+', encoding='utf-8')
LOG_FILE = open('log.log', 'w+', encoding='utf-8')


def exit_handler():
# ctrl + C works as well
log("Exiting")
ERR_FILE.close()
LOG_FILE.close()


# close files before exit
atexit.register(exit_handler)


def log(*args, files=[sys.stdout, LOG_FILE]):
# can also add timestamps etc.
cf = inspect.currentframe()
for f in files:
print("DEBUG", f"{inspect.stack()[1][1]}:{cf.f_back.f_lineno}", *args, file=f)
f.flush()


def log_err(*args, files=[ERR_FILE, sys.stderr]):
cf = inspect.currentframe()
for f in files:
print("ERROR", f"{inspect.stack()[1][1]}:{cf.f_back.f_lineno}", *args, file=f)
f.flush()


log("Hello World!")
log_err("error")

输出

DEBUG sample.py:29 Hello World!
ERROR sample.py:30 error
DEBUG sample.py:9 Exiting

下面是一个打印文件名和行号的简短函数。

from inspect import currentframe, getframeinfo




def HERE(do_print=True):
''' Get the current file and line number in Python script. The line
number is taken from the caller, i.e. where this function is called.


Parameters
----------
do_print : boolean
If True, print the file name and line number to stdout.


Returns
-------
String with file name and line number if do_print is False.


Examples
--------
>>> HERE() # Prints to stdout


>>> print(HERE(do_print=False))
'''
frameinfo = getframeinfo(currentframe().f_back)
filename = frameinfo.filename.split('/')[-1]
linenumber = frameinfo.lineno
loc_str = 'File: %s, line: %d' % (filename, linenumber)
if do_print:
print('HERE AT %s' % (loc_str))
else:
return loc_str

用法:

HERE() # Prints to stdout
# Output: HERE AT File: model.py, line: 275


print(HERE(False)) # Retrieves string and prints it.
# Output: File: model.py, line: 276