我正在一个修饰器库上工作,该修饰器库正在修改函数的关键字参数,并且该库正在执行我想要的操作,但是在调试时,每当调用用户函数时,调试器必须传递装饰器库代码。
我将装饰器实现为一个类(请参见https://github.com/mapa17/configfy/blob/master/configfy/decorator.py)
,用户函数由以下库代码包装:
def __call__(self, *args, **kwargs):
if self.needs_wrapping:
self.needs_wrapping = False
self.func = args[0]
functools.update_wrapper(self, self.func)
self.kwargs = self.__get_kw_args(self.func)
# If config file is specified in decorator, new kwargs can be precalculated!
if self.config is not None:
self.new_kwargs = self._get_new_kwargs()
return self
# Use precalculated kwargs if available
if self.new_kwargs is None:
new_kwargs = self._get_new_kwargs()
else:
new_kwargs = self.new_kwargs
# Overwrite them with any passed arguments; passed arguments have priority!
new_kwargs.update(kwargs)
# Call target (aka user) function with altered kwargs
return self.func(*args, **new_kwargs)
那么调试时是否有可能跳过该库代码?
答案 0 :(得分:1)
装饰器没有什么神奇的。 @decorator
语法只是语法糖,因此在您编写时:
@decorate
def some_func(...):
# ...
从技术上讲,真正发生的事情是:
def some_func(...):
# ...
some_func = decorate(some_func)
IOW,不,没有办法“使装饰器对调试器透明”,因为“装饰器”只是一个普通的可调用对象(通常但不一定)返回另一个普通的可调用对象-实际上,没有“装饰器”之类的东西,可调用对象就是装饰器(如果您这样使用的话),仅此而已。
答案 1 :(得分:1)
正如@ bruno-desthuilliers所提到的,装饰器是用户功能的包装,无法以某种方式删除它。
可以做的是,使用 skip 选项see
使调试器跳过装饰器模块代码。由于我有兴趣使用pudb进行调试,因此我创建了一个pull请求,为pdb see启用了类似功能
对于pdb
import pdb
from configfy import configfy as cfy
@cfy
def fuu(kw_me=42):
print(kw_me)
if __name__ == '__main__':
pdb.Pdb(skip=['configfy.*']).set_trace()
fuu()
对于pudb(如果接受了拉取请求)
import pudb
from configfy import configfy as cfy
# Prevent pudb from stepping into the decorator library code
pudb._get_debugger(skip=['configfy.*'])
@cfy
def fuu(kw_me=42):
print(kw_me)
if __name__ == '__main__':
pudb.set_trace()
fuu()