gpt4 book ai didi

python - 处理异常后如何从上次尝试的指令继续执行帧?

转载 作者:太空狗 更新时间:2023-10-29 18:05:53 25 4
gpt4 key购买 nike

我想通过将所需的缺失变量注入(inject)帧来处理 NameError 异常,然后从上次尝试的指令继续执行。

下面的伪代码应该可以说明我的需求。

def function():
return missing_var

try:
print function()

except NameError:

frame = inspect.trace()[-1][0]

# inject missing variable
frame.f_globals["missing_var"] = ...

# continue frame execution from last attempted instruction
exec frame.f_code from frame.f_lasti

Read the whole unittest on repl.it

注意事项

背景

代码在一个由父进程控制的从属进程中运行。任务(实际上是函数)写在父级中,后者使用 dill 传递给从属.我希望某些任务(在从进程中运行)尝试从父进程的外部范围访问变量,我希望从进程即时向父进程请求这些变量。

p.s.:我不希望这种魔法在生产环境中运行。

最佳答案

与各种评论者所说的相反,“错误恢复”异常处理在 Python 中是可能的。图书馆fuckit.py执行上述策略。它通过在导入时重写模块的源代码来消除错误,inserting try...except blocks around every statement并吞下所有异常。那么也许您可以尝试类似的策略?

不言而喻:该库只是一个笑话。永远不要在生产代码中使用它。


您提到您的用例是捕获对缺失名称的引用。您是否考虑过使用元编程在“智能”命名空间(例如 defaultdict)的上下文中运行您的代码? (与 fuckit.py 相比,这可能只是稍微好一点。)

from collections import defaultdict

class NoMissingNamesMeta(type):
@classmethod
def __prepare__(meta, name, bases):
return defaultdict(lambda: "foo")

class MyClass(metaclass=NoMissingNamesMeta):
x = y + "bar" # y doesn't exist

>>> MyClass.x
'foobar'

NoMissingNamesMetametaclass - 一种用于自定义 class 语句行为的语言结构。在这里,我们使用 __prepare__ 方法来自定义字典,该字典将在创建类时用作类的命名空间。因此,因为我们使用的是 defaultdict 而不是常规字典,元类是 NoMissingNamesMeta 的类永远不会得到 NameError。在创建类期间引用的任何名称都将自动初始化为 "foo"

这种方法类似于@AndréFratelli 手动从 Scope 对象请求延迟初始化数据的想法。在生产中我会这样做,而不是这个。元类版本需要更少的输入来编写客户端代码,但代价是更多的魔法。 (想象一下你自己在两年内调试这段代码,试图理解为什么不存在的变量被动态地引入范围!)

关于python - 处理异常后如何从上次尝试的指令继续执行帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34425356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com