如何制作一个也可以用作上下文管理器的 python 方法?



在我正在构建的图形 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"

您需要混合使用各种方法; 有一个函数 这被称为,返回一个上下文管理器,其中上下文管理器在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并返回一个从不使用的上下文管理器。当使用with调用时,它将重置self._fill当调用该上下文管理器的__exit__时。

需要明确的是,最好只使用单独的方法,这样您的"普通方法"方法更有效,并且您的上下文管理器方法可以更安全一些(实际上按照您的预期在__enter__中执行设置工作,缩小了竞争条件的窗口,这将阻止__exit__被调用(。

相关内容

最新更新