【发布时间】:2014-08-23 05:26:50
【问题描述】:
我希望在另一块代码的每一行之后运行一段代码。例如,希望能够在执行函数的下一行之前或之后评估全局变量。
例如,下面我尝试在foo() 函数的每一行之前打印'hello'。我认为装饰器可以帮助我,但它需要一些自省功能才能编辑我的 foo() 函数的每一行并在它之前或之后添加我想要的内容。
我正在尝试执行类似的操作:
>>> def foo():
... print 'bar'
... print 'barbar'
... print 'barbarbar'
>>> foo()
hello
bar
hello
barbar
hello
barbarbar
我该如何执行此操作? __code__ 对象会有帮助吗?我需要一个装饰器和内省吗?
编辑:这是该线程目标的另一个示例:
>>> def foo():
... for i in range(0,3):
... print 'bar'
>>> foo()
hello
bar
hello
bar
hello
bar
在这个新案例中,在打印每个“bar”之前,我想打印一个“hello”。
这样做的主要目标是能够在执行下一行代码之前执行另一个函数或测试任何类型的全局变量。想象一下,如果一个全局变量是True,那么代码转到下一行;而如果全局变量为False,则停止函数执行。
编辑: 在某种程度上,我正在寻找一种将代码注入另一个代码块的工具。
编辑: 感谢 unutbu 我已经实现了这个代码:
import sys
import time
import threading
class SetTrace(object):
"""
with SetTrace(monitor):
"""
def __init__(self, func):
self.func = func
def __enter__(self):
sys.settrace(self.func)
return self
def __exit__(self, ext_type, exc_value, traceback):
sys.settrace(None)
# http://effbot.org/zone/python-with-statement.htm
# When __exit__ returns True, the exception is swallowed.
# When __exit__ returns False, the exception is reraised.
# This catches Sentinel, and lets other errors through
# return isinstance(exc_value, Exception)
def monitor(frame, event, arg):
if event == "line":
if not running:
raise Exception("global running is False, exiting")
return monitor
def isRunning(function):
def defaultBehavior(*args):
with SetTrace(monitor):
ret = function(*args)
return ret
return defaultBehavior
@isRunning
def foo():
while True:
time.sleep(1)
print 'bar'
global running
running = True
thread = threading.Thread(target = foo)
thread.start()
time.sleep(3)
running = False
【问题讨论】:
标签: python decorator introspection