如何确定文件,功能和行号?

时间:2011-07-25 01:28:36

标签: python

在C ++中,我可以像这样打印调试输出:

printf(
   "FILE: %s, FUNC: %s, LINE: %d, LOG: %s\n",
   __FILE__,
   __FUNCTION__,
   __LINE__,
   logmessage
);

我如何在Python中做类似的事情?

9 个答案:

答案 0 :(得分:63)

有一个名为inspect的模块可以提供这些信息。

使用示例:

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

但是,请记住,有一种更简单的方法来获取当前正在执行的文件的名称:

print(__file__)

答案 1 :(得分:10)

例如

import inspect
frame = inspect.currentframe()
# __FILE__
fileName  =  frame.f_code.co_filename
# __LINE__
fileNo = frame.f_lineno

这里有更多http://docs.python.org/library/inspect.html

答案 2 :(得分:8)

以geowar的答案为基础:

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

如果您通常想要使用__LINE__,例如print(或任何其他时间隐含str()repr()),上述内容将允许您省略()

(将__call__作为练习添加到读者的明显扩展。)

答案 3 :(得分:4)

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

答案 4 :(得分:3)

我也对python中的__LINE__命令感兴趣。 我的起点是https://stackoverflow.com/a/6811020,我用一个元类对象扩展它。通过此修改,它具有与C ++相同的行为。

<body style="background-color:red;">
</body>

答案 5 :(得分:3)

你可以参考我的回答: https://stackoverflow.com/a/45973480/1591700

import sys
print sys._getframe().f_lineno

你也可以制作lambda函数

答案 6 :(得分:1)

哇,7岁的问题了:)

无论如何,采用Tugrul的答案并将其编写为debug类型的方法,它看起来可能像这样:

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

输出:

/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

答案 7 :(得分:0)

要在 Python 中获取行号而不导入整个 sys 模块...

首先导入 _getframe 子模块:

from sys import _getframe

然后调用 _getframe 函数并在您想知道行号时使用它的“f_lineno”属性:

print(_getframe().f_lineno)  # prints the line number

来自口译员:

>>> from sys import _getframe
... _getframe().f_lineno  # 2

来自官方 Python 文档的警告:

<块引用>

CPython 实现细节:此函数应仅用于内部和专用目的。不能保证在 Python 的所有实现中都存在。

换句话说:仅将此代码用于个人测试/调试原因。

有关 sys 模块和 _getframe() 函数/子模块的更多信息,请参阅 sys._getframe 上的官方 Python 文档。

基于Mohammad Shahid's answer(以上)。

答案 8 :(得分:0)

这是一个 tool 来回答这个古老而又新的问题! 我建议使用 icecream

<块引用>

您是否曾经使用过 print() 或 log() 来调试您的代码?当然,你 做。 IceCream,或简称 ic,让打印调试更甜蜜。

ic() 类似于 print(),但更好:

  1. 它打印表达式/变量名称及其值。
  2. 打字速度提高了 40%。
  3. 数据结构印刷得很漂亮。
  4. 输出以语法高亮显示。
  5. 它可以选择包含程序上下文:文件名、行号和父函数。

例如,我创建了一个模块 icecream_test.py,并将以下代码放入其中。

from icecream import ic
ic.configureOutput(includeContext=True)
def foo(i):
    return i + 333

ic(foo(123))

印刷品

ic| icecream_test.py:6 in <module>- foo(123): 456