- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
Python 中的堆栈跟踪显示文件路径。有什么方法可以让它们显示完全限定的函数名称吗?
例子:
class Foo(object):
def bar(self):
raise Exception, "Some error."
def inner():
return Foo().bar()
def outer():
return inner()
我希望我的输出看起来像这样:
In __main__.Foo.bar ("scratchpad.py", line 3)
__main__.inner ("scratchpad.py", line 6)
__main__.outer ("scratchpad.py", line 9)
Exception: Some error.
如果它改变了什么,我使用的是 Python 2.7。
这是我目前所拥有的:
import sys
class Foo(object):
def bar(self):
raise Exception, "Dummy value."
def inner():
"Inner function..."
return Foo().bar()
def outer():
return inner()
try:
outer()
except Exception, error:
traceback = sys.exc_info()[2]
while traceback is not None:
frame = traceback.tb_frame
print 'Name', frame.f_globals['__name__']+'.'+frame.f_code.co_name
docs = frame.f_code.co_consts[0]
if docs and docs != -1: # docs can be None or -1.
print 'Docs "%s"' % docs
print 'Args', frame.f_code.co_argcount
print 'File "%s", line %d' % (frame.f_code.co_filename, frame.f_lineno)
print
traceback = traceback.tb_next
当我运行它时,它会打印
$ python pretty-stack.py
Name __main__.<module>
Args 0
File "pretty-stack.py", line 28
Name __main__.outer
Args 0
File "pretty-stack.py", line 14
Name __main__.inner
Docs "Inner function..."
Args 0
File "pretty-stack.py", line 11
Name __main__.bar
Args 1
File "pretty-stack.py", line 7
快完成了,但我在处理重要用例时遇到了麻烦。例如,我无法为 Foo.bar()
获取类名 Foo
。
最佳答案
没有直接的方法从回溯中访问符号,因为只有“代码对象”是可访问的,并且,the Python docs on code objects说:
Unlike function objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects.
看来要找回回溯中涉及到的模块、函数、类,还需要搜索一下。
我有一个似乎有效的实验版本。此实现基于遍历代码对象引用的模块以查找引用相关代码对象的函数或方法。
from collections import namedtuple
import inspect
import sys
from nested.external import Foo
def inner(a, b='qux'):
"Inner function..."
return Foo().bar()
def outer(a, *args, **kwds):
return inner(a)
def resolve_signature(function):
"""Get a formatted string that looks like the function's signature."""
prgs, vrgs, kwds, defs = inspect.getargspec(function)
arguments = []
if defs:
for name in prgs[:len(defs)-1]:
arguments.append(name)
for i,name in enumerate(prgs[len(defs)-1]):
arguments.append('%s=%r'%(name,defs[i]))
else:
arguments.extend(prgs)
if vrgs:
arguments.append('*'+vrgs)
if kwds:
arguments.append('**'+kwds)
return '('+', '.join(arguments)+')'
def resolve_scope(module_name, code):
"""Resolve the scope name for a code object provided its module name."""
# Resolve module.
module = sys.modules.get(module_name, None)
if not module:
return '<hidden-module>' + '.' + code.co_name + '(?)'
# Check module's functions.
symbols = inspect.getmembers(module, inspect.isfunction)
for symbol_name,symbol_info in symbols:
if symbol_info.func_code is code:
scope = module_name + '.'
return scope + code.co_name + resolve_signature(symbol_info)
# Check module's classes.
symbols = inspect.getmembers(module, inspect.isclass)
for symbol_name,symbol_info in symbols:
# Check class' methods.
members = inspect.getmembers(symbol_info, inspect.ismethod)
for method_name,method_info in members:
if method_info.__func__.func_code is code:
scope = module_name + '.' + symbol_name + '.'
return scope + code.co_name + resolve_signature(method_info)
# Default to the thing's name. This usually happens
# when resolving the stack frame for module-level code.
return code.co_name
Frame = namedtuple('Frame', ['call', 'file', 'line', 'help'])
def pretty_stack(traceback=None):
"""Returns a simple stack frame."""
frames = []
if traceback is None:
traceback = sys.exc_info()[2]
while traceback is not None:
frame = traceback.tb_frame
call = resolve_scope(frame.f_globals['__name__'], frame.f_code)
path = frame.f_code.co_filename.replace('\\', '/')
line = frame.f_lineno
docs = frame.f_code.co_consts[0]
if docs == -1:
docs = None
frames.append(Frame(call, path, line, docs))
traceback = traceback.tb_next
return frames
try:
outer(1)
except Exception, error:
frames = pretty_stack()
for frame in frames:
print frame.call
print ' -> "%s", line %d.' % (frame.file, frame.line)
if frame.help:
print frame.help
print
当我运行它时,我得到类似的东西:
$ python pretty-stack.py
<module>
-> "pretty-stack.py", line 84.
__main__.outer(a, *args, **kwds)
-> "pretty-stack.py", line 14.
__main__.inner(a='qux')
-> "pretty-stack.py", line 11.
Inner function...
nested.external.Foo.bar(self)
-> "C:/Users/acaron/Desktop/nested/external.py", line 3.
请注意,这甚至会打印函数签名和文档字符串,这可能有助于调试。
在存在描述符和诸如此类的情况下,它可能无法按预期工作,我还没有尝试过非常复杂的用例。如果您发现它不起作用的情况,请告诉我,我会尝试修补它。
关于带有模块名称的 Python 回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14817788/
在我的类里面,我学习了 Prolog 回溯算法和 Rete forprop 算法,但我也被告知 Rete 可用于进行反向传播。 这是如何运作的?它在哪些方面与 Prolog 回溯相似/不同? 例如,这
两个 friend P1 和 P2 向共同的 friend P3 发送相同的消息 M。 然而由于一些网络损坏,P3 一次只能接收一个字符不知道接收到的字符是属于 P1 还是 P2。 此外,P3 可能会
我最近发了几个理解递归和回溯的问题,我觉得我现在得到了一些东西,并尝试编写一个测试,我确实解决了数独问题,但是当我以另一种格式编写代码时,代码卡了一会儿,返回False,说明这个问题无解。 grid
有人可以指导我或解释如何在 LISP 中执行回溯吗?任何示例或链接将不胜感激。我确实尝试过谷歌,但是他们都没有足够简单的例子让我理解。 谢谢 最佳答案 典型的方法是将不可变状态向下传递到调用堆栈,辅助
我正在使用 apache 2.2.14 运行 Backtrack 5 R2 (ubuntu) 的完全库存安装。我尝试运行一个简单的 index.html 文件,其中包含一些 javascript 代码
如何在 Javascript 中获取回溯? 理想的特征: 入口函数名称,或匿名函数的一些有意义的标识符, 每个级别的参数列表, 行号。 这可以用标准的 ECMAScript 完成吗? 如果没有,是否可
本文首发公众号:小码A梦 回溯算法是一种常见的算法,常见用于解决排列组合、排列问题、搜索问题等算法,在一个搜索空间中寻找所有的可能的解。通过向分支不断尝试获取所有的解,然后找到合适的
Python 是否支持为每个异常/引发/断言显示相同的自定义错误消息(无论代码在哪里中断)? 我目前对它的破解使用了一个装饰器。我有一个函数main它显示回溯很好,但我希望它也打印my_var (在函
输入: 3,4,8,7,3 5,S,7,2,3, 8,5,5,8,10 9,3,3,8,7 6,10,3,G,1 目标是找到从起点(S)到目标(G)的最佳路径。 我们可以向上、向下、向左、向右移动。
我想匹配一个包含“json”(出现超过 2 次)且两个“json”之间没有字符串“from”的字符串。 For example(what I want the string match or not)
我正在尝试使用回溯方法找到熄灯游戏的解决方案。我无法理解此过程的算法。我的方法是枚举从 0 到 2n2 - 1 的所有整数,并将每个整数转换为具有 n*n 位的二进制数。然后,将其分成n2个二进制数字
所以我正在阅读这本书《服从测试山羊》,在学习 Python 时我在第六章中遇到了一个问题。它说我应该能够运行我们在本章和前一章中设置的功能测试,没有错误;但是,我不断收到我不知道如何修复的回溯。 Tr
我需要一些关于 Android 日志文件反混淆的帮助。 问题是如果我有这样的异常: ... 10-16 10:03:10.488: E/AndroidRuntime(25723): Cau
我有一个看起来像这样的表: here | there | -------+-------+ {1,1} | {1,1} | {1,1} | {2,1} | {1,1} | {1,2} |
我写了一小段代码,它应该接受一个字符数组并让它看起来像计算机正在输入文本。很简单,对吧?但是当我运行它时,Terminal 告诉我: *** stack smashing detected ***:
Python 中的堆栈跟踪显示文件路径。有什么方法可以让它们显示完全限定的函数名称吗? 例子: class Foo(object): def bar(self): raise
我决定深入学习回溯的概念,我有以下任务: 给定N个投资者,M个城市,N×M个投资者偏好矩阵P(P[i,j]=1,当第i个投资者希望在第j个城市建矿池;P[i, j] = 0 那么他是中立的,当 P[i
设 E - 图 G 中所有边的集合问题是从G中找到顶点的最小子集S,它满足条件:S = E 中每个顶点的所有出边的总和 换句话说:边是街道,我们可以在顶点上放置路灯。如果我们在一个顶点上放置一盏路灯—
我正在尝试做这个我在查找面试问题时遇到的问题。我们被问及将 r 个硬币放置在 n*m 网格上的方法数量,使得每行和每列至少包含一个硬币。 我想到了一个回溯解决方案,按行主要顺序处理网格中的每个单元格,
我使用 DexGuard混淆。我有来自崩溃日志和映射文件的堆栈跟踪。当我运行 retrace.bat 并为其提供堆栈跟踪和映射文件时,输出仍然是混淆格式。 最佳答案 您是否在使用 ProGuard 的
我是一名优秀的程序员,十分优秀!