我怎样才能使 python 方法也可以用作上下文管理器?
How can I make a python method that also works as a context manager?
在图形中API我正在构建我想创建一个也可以用作上下文管理器的方法:
目前的方法是这样的:
class Gfx:
def __init__(self):
self._fill = None
def fill(self, color):
self._fill = color
我可以制作一个在使用后恢复状态的上下文管理器,如下所示:
class Gfx:
def __init__(self):
self._fill = None
@contextmanager
def fill(self, color):
"""Allow user to set fill color, then restore it"""
old_fill = self._fill
self._fill = color
yield
self._fill = old_fill
但是我怎样才能使它双向工作,具体取决于它的调用方式?
>>> gfx = Gfx()
>>> gfx.fill("red") # use as ordinary method
>>> print(self._fill)
"red"
>>> with gfx.fill("blue") # use as context manager
... print(gfx._fill)
"blue"
>>> print(gfx._fill)
"red"
你需要混合使用这些方法;有一个函数 this 被调用,返回一个上下文管理器,其中上下文管理器在 with
中未使用时被忽略。大致如下:
class Gfx:
def __init__(self):
self._fill = None
@contextmanager
def _fillctx(self, old_fill):
try:
yield
finally:
self._fill = old_fill
def fill(self, color):
"""Allow user to set fill color, then restore it"""
old_fill = self._fill
self._fill = color
return self._fillctx(old_fill)
当不使用 with
调用时,这会设置 self._fill
和 returns 一个从未使用过的上下文管理器。当使用 with
调用时,它将在调用该上下文管理器的 __exit__
时重置 self._fill
。
明确地说,最好只使用单独的方法,这样您的“普通方法”方法更有效,并且您的上下文管理器方法可以更安全一些(实际上在 __enter__
正如你应该做的那样,缩小 window 以防止 __exit__
被调用的竞争条件。
在图形中API我正在构建我想创建一个也可以用作上下文管理器的方法:
目前的方法是这样的:
class Gfx:
def __init__(self):
self._fill = None
def fill(self, color):
self._fill = color
我可以制作一个在使用后恢复状态的上下文管理器,如下所示:
class Gfx:
def __init__(self):
self._fill = None
@contextmanager
def fill(self, color):
"""Allow user to set fill color, then restore it"""
old_fill = self._fill
self._fill = color
yield
self._fill = old_fill
但是我怎样才能使它双向工作,具体取决于它的调用方式?
>>> gfx = Gfx()
>>> gfx.fill("red") # use as ordinary method
>>> print(self._fill)
"red"
>>> with gfx.fill("blue") # use as context manager
... print(gfx._fill)
"blue"
>>> print(gfx._fill)
"red"
你需要混合使用这些方法;有一个函数 this 被调用,返回一个上下文管理器,其中上下文管理器在 with
中未使用时被忽略。大致如下:
class Gfx:
def __init__(self):
self._fill = None
@contextmanager
def _fillctx(self, old_fill):
try:
yield
finally:
self._fill = old_fill
def fill(self, color):
"""Allow user to set fill color, then restore it"""
old_fill = self._fill
self._fill = color
return self._fillctx(old_fill)
当不使用 with
调用时,这会设置 self._fill
和 returns 一个从未使用过的上下文管理器。当使用 with
调用时,它将在调用该上下文管理器的 __exit__
时重置 self._fill
。
明确地说,最好只使用单独的方法,这样您的“普通方法”方法更有效,并且您的上下文管理器方法可以更安全一些(实际上在 __enter__
正如你应该做的那样,缩小 window 以防止 __exit__
被调用的竞争条件。