如何在不修改函数逻辑的情况下用Python Fire打印传入函数的参数?
使用Python Fire在不修改原函数逻辑的前提下拦截并打印参数
问题场景
我正在用Python的fire库开发简单命令行界面(CLI),现有代码如下:
import fire def main(a): print('hi') if __name__ == '__main__': fire.Fire(main)
运行命令:
$ python my_script.py 123
输出结果:
hi
需求是在打印hi前先打印传入main函数的参数(比如此处的123),但不能修改main函数的内部逻辑,也不想通过修改函数签名(例如添加*args)的方式改变Fire的参数处理逻辑。
可行解决方案
针对单个函数的场景
基于你尝试的包装器思路调整,直接包装目标函数即可,完全不改动原函数逻辑:
import fire def wrap_function(func): def wrapper(*args, **kwargs): # 打印拦截到的参数 print(f"传入的位置参数: {args}, 关键字参数: {kwargs}") # 调用原函数 return func(*args, **kwargs) return wrapper def main(a): print('hi') if __name__ == '__main__': # 将包装后的函数传入Fire fire.Fire(wrap_function(main))
运行测试:
$ python my_script.py 123
输出结果:
传入的位置参数: (123,), 关键字参数: {} hi
针对类命令的场景
你之前的包装器方案可以直接使用,稍作优化更贴合需求:
import fire class MyWrapper: def __init__(self, target): self.target = target def __getattr__(self, name): def method(*args, **kwargs): print(f"调用方法: {name}, 位置参数: {args}, 关键字参数: {kwargs}") return getattr(self.target, name)(*args, **kwargs) return method class MyCommands: def greet(self, name="World"): return f"Hello, {name}!" if __name__ == '__main__': fire.Fire(MyWrapper(MyCommands()))
运行测试:
$ python my_script.py greet --name Alice
输出结果:
调用方法: greet, 位置参数: (), 关键字参数: {'name': 'Alice'} Hello, Alice!
原理说明
- 包装器通过闭包或
__getattr__魔法方法拦截Fire传递的参数,先执行打印逻辑,再调用原函数/方法 - 完全保留原函数的签名和Fire的参数解析逻辑,不会因为修改函数签名导致CLI行为变化
内容的提问来源于stack exchange,提问作者Charlie Parker
相关产品推荐
相关产品推荐

