gpt4 book ai didi

python - 是否可以在上下文管理器的 __exit__() 方法中访问上下文对象(代码块)?

转载 作者:太空宇宙 更新时间:2023-11-03 13:45:37 24 4
gpt4 key购买 nike

如果它引发异常(可能多次,可能有延迟),我想在 exit() 方法中再次调用代码对象。我知道使用装饰器很容易做到,但我的动机是有时我只想重复一些我不想提取到单独函数并装饰它的代码片段。我正在寻找这些方面的东西:

class again(object):
def __enter__(self):
pass

def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is not None:
???? # Invoke the code object again
return True # eat exception

它会像这样使用:

x = 0
with again():
print x
x += 1
if x == 1:
raise Exception('I hate 1')

预期的输出是:

0
1

我可以找到一种方法来获取代码对象。上下文管理器属性似乎都没有引用它(我想它并不是真正需要的,因为它的工作只是在前后做一些事情)。

有可能吗?

最佳答案

with block 不作为单独的代码对象存在,所以没有。参见 this similar question .在那种情况下,提问者试图做相反的事情(从代码块内部访问上下文管理器),但作为 this answer解释说,with block 不是一个单独的范围,因此它实际上没有任何单独的状态。

你可以通过一个例子看到这一点:

import contextlib
import dis

@contextlib.contextmanager
def silly():
yield

def foo():
print "Hello"
with silly():
print "Inside"
print "Goodbye"

然后

>>> dis.dis(foo.__code__)
2 0 LOAD_CONST 1 (u'Hello')
3 PRINT_ITEM
4 PRINT_NEWLINE

3 5 LOAD_GLOBAL 0 (silly)
8 CALL_FUNCTION 0
11 SETUP_WITH 10 (to 24)
14 POP_TOP

4 15 LOAD_CONST 2 (u'Inside')
18 PRINT_ITEM
19 PRINT_NEWLINE
20 POP_BLOCK
21 LOAD_CONST 0 (None)
>> 24 WITH_CLEANUP
25 END_FINALLY

5 26 LOAD_CONST 3 (u'Goodbye')
29 PRINT_ITEM
30 PRINT_NEWLINE
31 LOAD_CONST 0 (None)
34 RETURN_VALUE

您可以看到 with block 的代码与其他所有内容一起位于函数的代码对象中。它不作为单独的代码对象存在,并且与函数的其余代码没有区别。您无法以任何理智的方式将其取出(我的意思是,如果不破解字节码)。

关于python - 是否可以在上下文管理器的 __exit__() 方法中访问上下文对象(代码块)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21248103/

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