我想在Python中调用函数时获得控制权(执行一些先发制人的任务(,而不修改源程序,例如,在调用test((时
def test(i : int, s: str) -> int:
pass
我希望调用一个函数myobserver,并有一些方法来检查(甚至可以修改?!(参数?把它想象成一个迷你调试器,例如,向不能/不应该修改的现有程序添加日志记录?
def myobserver(handle)
name = get_name(handle)
for n, arg in enumerate(get_arg_iterator(handle)):
print("Argument {n} of function {name}: {arg}")
ETA:我不是在寻找传统的decorator
,因为添加装饰器需要更改源代码。(从这个意义上说,装饰器比添加打印更好,但仍然相似,因为它们需要更改源代码。(
您正在寻找python装饰器:
from functools import wraps
def debugger(func):
@wraps(func)
def with_logging(*args, **kwargs):
print('"'+func.__name__+'({},{})"'.format(*args, **kwargs)+" was invoked")
# -------------------
# Your logic here
# -------------------
return func(*args, **kwargs)
return with_logging
@debugger
def test(i : int, s: str) -> int:
print('We are in test', i, s)
test(10, 'hello')
编辑
由于上面提到的decorator方法会干扰源代码(必须应用@
decorator(,我建议如下:
# This is source code to observe, should not be _touched_!
class SourceCode:
def __init__(self, label):
self.label = label
def test1(self, i, s):
print('For object labeled {}, we are in {} with param {}, {}'.format(self.label, 'test1', i, s))
def test2(self, k):
print('For object labeled {}, we are in {} with param {}'.format(self.label, 'test2', k))
我建议的是在编写钩子时进行一些手动操作,我不确定这是否可行(我刚刚想到,因此添加了(:
from functools import wraps
# the following is pretty much syntactic and generic
def hook(exist_func, debugger):
@wraps(exist_func)
def run(*args, **kwargs):
return debugger(exist_func, *args, **kwargs)
return run
# here goes your debugger
def myobserver(orig_func, *args, **kwargs):
# -----------------------
# Your logic goes here
# -----------------------
print('Inside my debugger')
return orig_func(*args, **kwargs)
# ---------------------------------
obj = SourceCode('Test')
# making the wrapper ready to receive
no_iterference_hook1 = hook(obj.test1, myobserver)
no_iterference_hook2 = hook(obj.test2, myobserver)
# call your debugger on the function of your choice
no_iterference_hook1(10, 'hello')
no_iterference_hook2('Another')