首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python多行表达式和堆栈跟踪

Python多行表达式和堆栈跟踪
EN

Stack Overflow用户
提问于 2012-07-16 19:34:41
回答 1查看 1.5K关注 0票数 0

我们在python项目中使用了一个简单的AssertTrue函数,我想修改它提供的输出,以打印从中调用它的代码语句。代码看起来像这样:

代码语言:javascript
复制
1 import traceback
2
3 def AssertTrue(expr, reason=None):
4     print traceback.format_stack()[-2]
5
6 AssertTrue(1 == 2,
7         reason='One is not equal to two')

输出:

代码语言:javascript
复制
File "/tmp/fisken.py", line 7, in <module>
  reason='One is not equal to two')

我想知道为什么traceback.format_stack只给了我第7行的代码,语句从第6行开始,我希望在输出中看到的表达式也在同一行。traceback不处理多行函数调用吗?

(不要介意有更好的方法来做AssertTrue(...)。我只是想知道为什么traceback.format_stack (和.extract_stack)的行为不像我期望的那样。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-17 18:19:22

不处理多行函数调用吗?

许多函数长达数十甚至数百行。如果traceback确实打印了整个函数,那么堆栈跟踪将变得难以理解。所以我猜你看到的是一种试图让事情保持干净和最小化的尝试。

我收集了一些类似问题的答案:

考虑到它检查只能获得整个函数的源代码(如果源代码在路径上可用),我可以向您提供以下内容:

代码语言:javascript
复制
import traceback
import inspect
import gc

def giveupthefunc(frame):
    code  = frame.f_code
    globs = frame.f_globals
    functype = type(lambda: 0)
    funcs = []
    for func in gc.get_referrers(code):
        if type(func) is functype:
            if getattr(func, "func_code", None) is code:
                if getattr(func, "func_globals", None) is globs:
                    funcs.append(func)
                    if len(funcs) > 1:
                        return None
    return funcs[0] if funcs else None


def AssertTrue(expr, reason=None):
    print traceback.format_stack()[-2]
    frame = inspect.currentframe().f_back
    func = giveupthefunc(frame)
    if func:
        source = inspect.getsourcelines(func)
        i = source[1]
        for line in source[0]:
            print i, ":", line,
            i += 1



def my_fun():
    AssertTrue(1 == 2,
             reason='One is not equal to two')

my_fun()

这会产生:

代码语言:javascript
复制
/Library/Frameworks/Python.framework/Versions/2.7/bin/python /Users/xxxx/Documents/PycharmProjects/scratchpad/test.py
  File "/Users/xxxx/Documents/PycharmProjects/scratchpad/test.py", line 35, in my_fun
    reason='One is not equal to two')

33 : def my_fun():
34 :     AssertTrue(1 == 2,
35 :              reason='One is not equal to two')
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11503419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档