我想在另一個代碼塊的每行之後運行一段代碼。例如,希望能夠在執行函數的下一行之前或之後評估全局變量。Python:在代碼塊的每一行添加代碼例程
例如,下面我嘗試在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
在這種新情況下,打印每個「條」之前,我想打印一個「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
非常感謝,這似乎是接近於此,你說得對,線程的主要目的不是調試,而是更多的是能夠阻止正在執行的代碼塊在執行代碼的每一行之前更改此函數將評估的另一個全局變量的值。 如果全局切換爲false,則這將在代碼的每一行內添加一個搶佔點,然後如果切換爲true,那麼函數停止withtout到結束=>然後該函數執行該行並轉到下一個一個 我是否明確了這一點? – afiah
是的,您可以檢查*並從'monitor'內更改本地和全局值的值。 – unutbu
謝謝,但是我可以停止監視功能的當前執行嗎?在這種情況下,停止執行foo()? (在某種程度上,我可以在我想要的時候添加返回行以完成我的功能?) – afiah