如何让类方法与python中的上下文管理器交互?

2024-03-28 17:56:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码包含一些对象,这些对象通过Pythons的“with”语句使用,以确保它们安全地关闭。你知道吗

现在我想创建一个类,其中方法可以与这些对象交互。你知道吗

例如,我的代码实际上如下所示:

with ... as a, with ... as b:
    # do something with a and b here
    call_method(a, b)  # pass a and b here

我想把它放到一个类中,所以它看起来像这样:

class Something(object):

    def __init__(self):
        with ... as a:
            self.a = a
        with ... as b:
            self.b = b

    def do_something(self):
        # do something with self.a and self.b
        self.call_method(self.a, self.b)

    def call_method(self, a, b)
        # do more with a, b

对象需要一直保持“打开”。你知道吗

我不知道如何做到这一点,那我该怎么做呢?你知道吗


Tags: and对象方法代码selfheredefas
2条回答

您可以使类本身成为上下文管理器:

class Something(object):

    def __init__(self):
        self.a = a
        self.b = b

    def __enter__(self):
        self.a_e = a.__enter__(self)
        self.b_e = b.__enter__(self)
    def __exit__(self, *x):
        xb = False
        try:
            xb = self.b_e(*x)
        finally:
            xa = self.a_e(*x)
        return xa or xb # make sure both are called.
    def do_something(self):
        # do something with self.a and self.b
        # - or, if present, with a_e, b_e
        self.call_method(self.a, self.b)
    def call_method(self, a, b)
        # do more with a, b

这只是一个原始的想法。为了使它正常工作,您必须对try:except:finally:做更多的工作。你知道吗

你可以用它和

with Something(x, y) as sth:
    sth.do_something()

它得到适当的__enter__()ed和__exit__()ed

类中没有要管理的“上下文”,请不要在__init__中使用with。你必须用其他方式关闭这些文件。你知道吗

如果希望在方法中出现异常时关闭文件对象,则始终可以使用try:finally:

def call_method(self, a, b)
    try:
        # do more with a, b
    finally:
        self.a.close()
        self.b.close()

但是如果你真的想在那个时候关闭这些文件的话,这在很大程度上取决于你想对它们做什么。你知道吗

如果您的实例本身应该在特定的上下文中使用(例如,在实例打开文件的过程中,有一个比开始和结束都多的代码块),那么您可以通过实现context manager special methods使成为上下文管理器。你知道吗

作为类API的设计者,您将知道文件需要打开多长时间。这在很大程度上取决于关闭文件时如何使用实例。你知道吗

相关问题 更多 >