python中使用sys模板和logging模块获取行号和函数名的方法
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!現在應該不用再抱怨取不到行號和函數名了吧~
=============================================================================
后來發現,其實也可以有更簡單的方法,如下:
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模块获取行号和函数名的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十天冲刺---Day8
- 下一篇: Python爬虫入门三urllib库基本