From: http://www.jb51.net/article/49026.htm

这篇文章主要介绍了python中使用sys模板和logging模块获取行号和函数名的方法,需要的朋友可以参考下

对于python,这几天一直有两个问题在困扰我:
1.python中没办法直接取得当前的行号和函数名。这是有人在论坛里提出的问题,底下一群人只是在猜测python为什么不像__file__一样提供__line__和__func__,但是却最终也没有找到解决方案。
2.如果一个函数在不知道自己名字的情况下,怎么才能递归调用自己。这是我一个同事问我的,其实也是获取函数名,但是当时也是回答不出来。

但是今晚!所有的问题都有了答案。
一切还要从我用python的logging模块说起,logging中的format中是有如下选项的:

复制代码 代码如下:

%(name)s            Name of the logger (logging channel)
%(levelno)s         Numeric logging level for the message (DEBUG, INFO,
                    WARNING, ERROR, CRITICAL)
%(levelname)s       Text logging level for the message ("DEBUG", "INFO",
                    "WARNING", "ERROR", "CRITICAL")
%(pathname)s        Full pathname of the source file where the logging
                    call was issued (if available)
%(filename)s        Filename portion of pathname
%(module)s          Module (name portion of filename)
%(lineno)d          Source line number where the logging call was issued
                    (if available)
%(funcName)s        Function name
%(created)f         Time when the LogRecord was created (time.time()
                    return value)
%(asctime)s         Textual time when the LogRecord was created
%(msecs)d           Millisecond portion of the creation time
%(relativeCreated)d Time in milliseconds when the LogRecord was created,
                    relative to the time the logging module was loaded
                    (typically at application startup time)
%(thread)d          Thread ID (if available)
%(threadName)s      Thread name (if available)
%(process)d         Process ID (if available)
%(message)s         The result of record.getMessage(), computed just as
                    the record is emitted

也就是说,logging是能够获取到调用者的行号和函数名的,那会不会也可以获取到自己的行号和函数名呢?
我们来看一下源码,主要部分如下:

复制代码 代码如下:

def currentframe():
    """Return the frame object for the caller's stack frame."""
    try:
        raise Exception
    except:
        return sys.exc_info()[2].tb_frame.f_back
def findCaller(self):
    """
    Find the stack frame of the caller so that we can note the source
    file name, line number and function name.
    """
    f = currentframe()
    #On some versions of IronPython, currentframe() returns None if
    #IronPython isn't run with -X:Frames.
    if f is not None:
        f = f.f_back
    rv = "(unknown file)", 0, "(unknown function)"
    while hasattr(f, "f_code"):
        co = f.f_code
        filename = os.path.normcase(co.co_filename)
        if filename == _srcfile:
            f = f.f_back
            continue
        rv = (co.co_filename, f.f_lineno, co.co_name)
        break
    return rv
def _log(self, level, msg, args, exc_info=None, extra=None):
    """
    Low-level logging routine which creates a LogRecord and then calls
    all the handlers of this logger to handle the record.
    """
    if _srcfile:
        #IronPython doesn't track Python frames, so findCaller throws an
        #exception on some versions of IronPython. We trap it here so that
        #IronPython can use logging.
        try:
            fn, lno, func = self.findCaller()
        except ValueError:
            fn, lno, func = "(unknown file)", 0, "(unknown function)"
    else:
        fn, lno, func = "(unknown file)", 0, "(unknown function)"
    if exc_info:
        if not isinstance(exc_info, tuple):
            exc_info = sys.exc_info()
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
    self.handle(record)

我简单解释一下,实际上是通过在currentframe函数中抛出一个异常,然后通过向上查找的方式,找到调用的信息。其中

复制代码 代码如下:

rv = (co.co_filename, f.f_lineno, co.co_name)

的三个值分别为文件名,行号,函数名。(可以去http://docs.python.org/library/sys.html来看一下代码中几个系统函数的说明)
OK,如果已经看懂了源码,那获取当前位置的行号和函数名相信也非常清楚了,代码如下:

复制代码 代码如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
#=============================================================================
#  FileName:        xf.py
#  Description:     获取当前位置的行号和函数名
#  Version:         1.0
#=============================================================================
'''
import sys
def get_cur_info():
    """Return the frame object for the caller's stack frame."""
    try:
        raise Exception
    except:
        f = sys.exc_info()[2].tb_frame.f_back
    return (f.f_code.co_name, f.f_lineno)

def callfunc():
    print get_cur_info()

if __name__ == '__main__':
    callfunc()

输入结果是:

复制代码 代码如下:
('callfunc', 24)

符合预期~~
哈哈,OK!现在应该不用再抱怨取不到行号和函数名了吧~

=============================================================================
后来发现,其实也可以有更简单的方法,如下:

复制代码 代码如下:
import sys
def get_cur_info():
    print sys._getframe().f_code.co_name
    print sys._getframe().f_back.f_code.co_name
get_cur_info()

调用结果是:

复制代码 代码如下:
get_cur_info
<module>

您可能感兴趣的文章:

  • python获取Linux下文件版本信息、公司名和产品名的方法
  • python获取文件版本信息、公司名和产品名的方法
  • python实现批量获取指定文件夹下的所有文件的厂商信息
  • Python获取电脑硬件信息及状态的实现方法
  • 使用python编写脚本获取手机当前应用apk的信息
  • 使用 Python 获取 Linux 系统信息的代码
  • 使用Python获取Linux系统的各种信息
  • python中使用urllib2获取http请求状态码的代码例子
  • Python 获取新浪微博的最新公共微博实例分享
  • python通过scapy获取局域网所有主机mac地址示例
  • python使用ctypes模块调用windowsapi获取系统版本示例
  • 使用Python获取CPU、内存和硬盘等windowns系统信息的2个例子
  • Python获取文件ssdeep值的方法

python中使用sys模板和logging模块获取行号和函数名的方法相关推荐

  1. python pandas获取行号_python获取行号和函数名

    敢用自己的名字做软件名字的,都有非常强大的自信.比如,垠语言什么的. awk的命名得自于它的三个创始人姓别的首字母,都是80来岁的老爷爷了.当然也有四个人的组合:流行的GoF设计模式.但对于我这游戏爱 ...

  2. python 打印当前行号_python中获取当前位置所在的行号和函数名(转)

    http://www.vimer.cn/2010/12/%E5%9C%A8python%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E4%BD%8D%E7 ...

  3. python查找指定字符所在行号_在python中获取当前位置所在的行号和函数名

    对于python,这几天一直有两个问题在困扰我: 1.python中没办法直接取得当前的行号和函数名.这是有人在论坛里提出的问题,底下一群人只是在猜测python为什么不像__file__一样提供__ ...

  4. python获取行号_在python中获取当前位置所在的行号和函数名

    python中没办法直接取得当前的行号和函数名.这是有人在论坛里提出的问题,底下一群人只是在猜测python为什么不像__file__一样提供__line__和__func__,但是却最终也没有找到解 ...

  5. python中calendar怎么用_Python时间模块datetime、time、calendar的使用方法

    import time import datetime #两日期相减 d1 = datetime.datetime(2005, 2, 16) d2 = datetime.datetime(2004, ...

  6. mysql 中关于获取行号@rownum:=@rownum+1

    mysql中没有获取行号的函数,因此需要通过一些自定义语句来进行获取.通常做法是,通过定义用户变量@rownum来保存表中的数据.通过赋值语句@rownum:=@rownum+1来累加达到递增行号. ...

  7. Mysql中获取行号

      mysql中是没有获取行号的函数的,但是我们可以通过定义变量来获取行号下面就举个简单的例子. 表中数据如下所示: 接下来对价格'price'进行排序标记行号,sql如下: SELECT @rown ...

  8. Python之路(第十七篇)logging模块

    一.logging模块 (一).日志相关概念 日志是一种可以追踪某些软件运行时所发生事件的方法.软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情.一个事件可以用一个可包含可选变 ...

  9. Python中第三方的库(library)、模块(module),包(package)的安装方法以及ImportError: No module named...

    Python中,想要安装第三方安装包,即third library,package等,对于熟悉的人来说,很简单. 但是对于新手,至少对于之前的我,很难,往往只是安装一个很小的包,都被搞得一头雾水. 现 ...

最新文章

  1. 专设AI周会 高管悉数到场 微软CEO有多重视人工智能?
  2. vaspkit使用_VASPKIT校正气体分子自由能
  3. linux shell 删除两个文件相同部分
  4. Windows Phone7 -- ApplicationBar具体使用说明(设置显示迷你模式和背景半透明模式)...
  5. RedHat6配置网络yum源
  6. Android Lifecycle 生命周期组件详解
  7. ios网址解析中,中文部分如何处理
  8. 动态规划训练17 [Super Jumping! Jumping! Jumping! HDU - 1087 ]
  9. mysql触发器如何获取当前表名_MCGS pro组态环境下,如何获取当前用户名,在画面上显示?...
  10. 设计模式学习笔记——享元(Flyweight)模式
  11. 服务器块格式不正确的是什么,c#-服务器标签格式不正确.(databinder.eval)
  12. symfony api 异常处理_dubbo-RPC服务的异常处理
  13. mysql+存储器_mysql内存储器计算公式_mysql
  14. 【LOJ#6036】[雅礼集训2017Day4]编码
  15. PX4 FMU [7] rgbled [转载]
  16. CODEVS 3027 线段覆盖2
  17. 苹果电脑关于命令行的操作
  18. ASTC图片纹理压缩探讨
  19. 拿下阿里三面是后,面试官问我:你是怎么学习Redis的?
  20. [乐意黎原创] 删除QQ的MiniBrowser浏览器,QQ聊天会话中点击链接直接用默认浏览器中打开

热门文章

  1. csu 1008 - Horcrux
  2. sql,dateadd,datediff
  3. python内置函数多少个_每个数据科学家都应该知道的10个Python内置函数
  4. java职业技能了解精通_如何通过精通数字分析来提升职业生涯的发展,第8部分...
  5. leetcode441. 排列硬币(二分查找)
  6. leetcode1282. 用户分组(贪心算法)
  7. leetcode40. 组合总和 II(回溯)
  8. Docker初学者指南-如何创建您的第一个Docker应用程序
  9. figma下载_Figma重新构想的团队库
  10. 为什么虚拟助手的前途一片光明