- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
您的程序刚刚暂停在 pdb.set_trace()
上。
有没有办法猴子修补当前正在运行的函数,并“恢复”执行?
这可以通过调用框架操作实现吗?
一些上下文:
通常,我会有一个处理大量数据的复杂函数,但先验不知道我会找到什么样的数据:
def process_a_lot(data_stream):
#process a lot of stuff
#...
data_unit= data_stream.next()
if not can_process(data_unit)
import pdb; pdb.set_trace()
#continue processing
这个方便的构造在遇到未知数据时会启动交互式调试器,因此我可以随意检查它并更改 process_a_lot
代码以正确处理它。
这里的问题是,当 data_stream
很大时,您真的不想再次咀嚼所有数据(假设 next
很慢,所以您无法保存您已有的内容并在下次运行时跳过)
当然你也可以在调试器中一次随意替换其他函数。您也可以替换函数本身,但它不会更改当前的执行上下文。
编辑:由于有些人正在偏离轨道:我知道有很多方法可以构建您的代码,使您的处理函数与 process_a_lot
分开。我并没有真正询问构建代码的方法,而是询问如何从代码未准备好处理替换的情况中恢复(在运行时)。
最佳答案
首先是(原型(prototype))解决方案,然后是一些重要的注意事项。
# process.py
import sys
import pdb
import handlers
def process_unit(data_unit):
global handlers
while True:
try:
data_type = type(data_unit)
handler = handlers.handler[data_type]
handler(data_unit)
return
except KeyError:
print "UNUSUAL DATA: {0!r}". format(data_unit)
print "\n--- INVOKING DEBUGGER ---\n"
pdb.set_trace()
print
print "--- RETURNING FROM DEBUGGER ---\n"
del sys.modules['handlers']
import handlers
print "retrying"
process_unit("this")
process_unit(100)
process_unit(1.04)
process_unit(200)
process_unit(1.05)
process_unit(300)
process_unit(4+3j)
sys.exit(0)
和:
# handlers.py
def handle_default(x):
print "handle_default: {0!r}". format(x)
handler = {
int: handle_default,
str: handle_default
}
在 Python 2.7 中,这为您提供了一个字典,将预期/已知类型链接到处理每种类型的函数。如果没有可用于某个类型的处理程序,用户将自己放入调试器中,让他们有机会使用适当的处理程序修改 handlers.py
文件。在上面的示例中,没有用于 float
或 complex
值的处理程序。当它们出现时,用户将不得不添加适当的处理程序。例如,可以添加:
def handle_float(x):
print "FIXED FLOAT {0!r}".format(x)
handler[float] = handle_float
然后:
def handle_complex(x):
print "FIXED COMPLEX {0!r}".format(x)
handler[complex] = handle_complex
这是运行的样子:
$ python process.py
handle_default: 'this'
handle_default: 100
UNUSUAL DATA: 1.04
--- INVOKING DEBUGGER ---
> /Users/jeunice/pytest/testing/sfix/process.py(18)process_unit()
-> print
(Pdb) continue
--- RETURNING FROM DEBUGGER ---
retrying
FIXED FLOAT 1.04
handle_default: 200
FIXED FLOAT 1.05
handle_default: 300
UNUSUAL DATA: (4+3j)
--- INVOKING DEBUGGER ---
> /Users/jeunice/pytest/testing/sfix/process.py(18)process_unit()
-> print
(Pdb) continue
--- RETURNING FROM DEBUGGER ---
retrying
FIXED COMPLEX (4+3j)
好的,这样基本上就可以了。您可以将其改进和调整为更适合生产的形式,使其与 Python 2 和 3 等兼容。
在这样做之前,请深思熟虑。
这种“实时修改代码”的方法是一种极其脆弱且容易出错的方法。它鼓励您在紧要关头进行实时修复。这些修复可能没有经过良好或充分的测试。几乎根据定义,你刚刚发现你正在处理一个新类型 T。你还不太了解 T,它为什么会发生,它的边缘情况和失败模式可能是什么,等等。如果你的“修复”代码或热补丁不起作用,然后呢?当然,您可以加入更多的异常处理,捕获更多的异常类,并可能继续。
Web 框架,如 Flask具有基本上以这种方式工作的 Debug模式。但那些是 Debug模式,通常不适合生产。此外,如果您在调试器中输入了错误的命令怎么办?不小心输入了“quit”而不是“continue”,整个程序就结束了,随之而来的是你希望继续处理的愿望。如果这是用于调试(可能是探索新型数据流),请访问。
如果这是用于生产,请考虑使用 strategy that sets aside unhandled-types用于异步、带外检查和校正,而不是将开发人员/操作人员置于实时处理流程的中间。
关于python - "Online"函数的猴子修补,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26763993/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我尝试过sp_helpindex,但它显示的是具有索引的列,而不是包含的列。请告诉我如何列出包含列(非键)的所有索引? 最佳答案 针对目录 View 尝试此 T-SQL 查询: SELECT
我是一名优秀的程序员,十分优秀!