Python 3.9 REPL环境下运行时修改run装饰函数自动添加Loop调用可行吗?
问题1 省略Loop调用的实现方案
完全可以在现有的run()装饰器逻辑里实现自动追加Loop调用,不需要用户修改业务代码,只要调整func_wrapper的执行逻辑即可:
原来的try块是直接返回用户函数的执行结果,你改成先执行用户的函数逻辑,没有抛出异常的情况下自动调用Loop()就行,修改后的装饰器核心代码如下:
from functools import wraps def run(beat=1, bar=1, loop=True): # 新增loop参数支持按需关闭自动循环 def run_inner(func): @wraps(func) def func_wrapper(*args, **kwargs): try: # 先执行用户定义的函数逻辑 result = func(*args, **kwargs) # 无异常则自动调度循环 if loop: Loop(func_wrapper) return result # 原有异常捕获逻辑保持不变 except NameError as e: print("You named something incorrectly: {}.".format(e)) Stop(func) return None except ValueError as e: print("Check your numbers: {}.".format(e)) Stop(func) return None except TypeError as e: print("Something ended up in the wrong pipe: {}.".format(e)) Stop(func) return None except AttributeError as e: print("Whoops. Correct your code please : {}.".format(e)) Stop(func) return None # 原有函数注册逻辑保持不变 if func.__name__ not in list(Track._memory.keys()): Start(func_wrapper, beat=0, bar=1) return func_wrapper return run_inner
这个方案完全兼容你现有逻辑,无需用户调整写法,刚好符合你期望的简化效果。如果存在不需要自动循环的场景,用户只要写成@run(loop=False)即可,灵活性也得到了保留。
问题2 修改REPL中动态执行函数的源码可行性
技术上可以实现,但你的场景完全不需要使用这种方案。
- 可行路径:你可以通过
inspect.getsource()获取REPL中定义函数的源码,用AST模块解析修改语法树,追加Loop()调用的节点后重新编译,替换原函数的实现。 - 但该方案缺陷非常明显:REPL环境中定义的函数部分场景下无法获取源码、处理边界情况(比如函数内部已有return语句、嵌套逻辑)的复杂度很高,远不如装饰器包裹的方案稳定可靠,完全没必要在你的场景中采用这种实现。
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

