有没有办法在运行时获取装饰器函数的参数?我正在研究的项目非常庞大,重写受影响的代码将是一项巨大的工作。我需要一个动态解决方案来列出分配给函数列表的所有“类别”。为此,我想避免使用超级hacky解决方案,例如通过我的所有模块进行复制。可以通过检查调用堆栈中的帧来完成吗?
在我们的环境中,函数是对象方法,我们也使用链式装饰器。为了便于理解,我把这段代码放在一起。
如果这是不可能的,我可以为项目的某些部分组建另一个装饰器,尽管它会增加更多的复杂性。但欢迎任何解决我的问题的建议。
def check(*args):
# do something project relevant, so just return True
return True
def decorate(*categories):
def wrap(f):
def wrap_check_categories(*args, **kwargs):
if check(*categories):
return f(*args, **kwargs)
else:
raise Exception
return wrap_check_categories
return wrap
def get_categories(f):
'''Returns decorator parameters'''
# ... do some magic here
raise NotImplementedError
@decorate('foo', 'bar')
def fancy_func(*args, **kwargs):
return args, kwargs
def main():
## should output ['foo', 'bar']
print get_categories(fancy_func)
if __name__ == '__main__':
main()
答案 0 :(得分:2)
修改装饰器以将类别存储在装饰函数的属性(例如_args
)中:
def check(*args):
# do something project relevant, so just return True
return True
def decorate(*categories):
def wrap(f):
def wrap_check_categories(*args, **kwargs):
if check(*categories):
return f(*args, **kwargs)
else:
raise Exception
wrap_check_categories._args = categories # <-- store the categories
return wrap_check_categories
return wrap
def get_categories(f):
'''Returns decorator parameters'''
# ... do some magic here
return f._args
@decorate('foo', 'bar')
def fancy_func(*args, **kwargs):
return args, kwargs
def main():
## should output ['foo', 'bar']
print get_categories(fancy_func)
if __name__ == '__main__':
main()
产量
('foo', 'bar')