gpt4 book ai didi

python - 上下文管理器中的 __init__ 与 __enter__

转载 作者:IT老高 更新时间:2023-10-28 20:31:25 25 4
gpt4 key购买 nike

据我了解,上下文管理器的 __init__()__enter__() 方法只被调用一次,一个接一个,没有任何机会其他要在两者之间执行的代码。将它们分成两种方法的目的是什么,我应该在每种方法中放入什么?

编辑:抱歉,没有关注文档。

编辑 2:实际上,我感到困惑的原因是因为我在考虑 @contextmanager 装饰器。使用 @contextmananger 创建的上下文管理器只能使用一次(第一次使用后生成器会耗尽),因此通常使用 with 语句中的构造函数调用编写它们;如果这是使用 with 语句的唯一方法,那么我的问题将是有道理的。当然,实际上,上下文管理器比 @contextmanager 可以创建的更通用;特别是上下文管理器通常可以被重用。希望这次我做对了?

最佳答案

As far as I understand, __init__() and __enter__() methods of the context manager are called exactly once each, one after another, leaving no chance for any other code to be executed in between.

而且你的理解是不正确的。 __init__ 在创建对象时调用,__enter__ 在使用 with 语句输入时调用,这是两个截然不同的东西。通常是在 with 初始化中直接调用构造函数,没有中间代码,但不一定是这种情况。

考虑这个例子:

class Foo:
def __init__(self):
print('__init__ called')
def __enter__(self):
print('__enter__ called')
return self
def __exit__(self, *a):
print('__exit__ called')

myobj = Foo()

print('\nabout to enter with 1')
with myobj:
print('in with 1')

print('\nabout to enter with 2')
with myobj:
print('in with 2')

myobj 可以单独初始化,并在多个with block 中输入:

输出:

__init__ called

about to enter with 1
__enter__ called
in with 1
__exit__ called

about to enter with 2
__enter__ called
in with 2
__exit__ called

此外,如果 __init____enter__ 没有分开,甚至无法使用以下内容:

def open_etc_file(name):
return open(os.path.join('/etc', name))

with open_etc_file('passwd'):
...

因为初始化(在 open 内)明显与 with 条目分开。


contextlib.manager 创建的经理是单入的,但它们也可以在 with block 之外构造。举个例子:

from contextlib import contextmanager

@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)

您可以将其用作:

def heading(level=1):
return tag('h{}'.format(level))

my_heading = heading()
print('Below be my heading')
with my_heading:
print('Here be dragons')

输出:

Below be my heading
<h1>
Here be dragons
</h1>

但是,如果您尝试重用 my_heading(因此,tag),您将得到

RuntimeError: generator didn't yield

关于python - 上下文管理器中的 __init__ 与 __enter__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39611520/

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