类实例中的上下文管理器

2024-04-20 01:07:25 发布

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

我想创建一个特定于另一个类实例的上下文管理器类。我可以通过调用创建类的方法来完成,但我不确定这是最好、最好的方法:

class MyClass(object):
    def __init__(self):
        self.level = 0
        self.Nest = self.create_context_manager()
    def inclev(self):
        self.level += 1
    def declev(self):
        self.level -= 1

    def create_context_manager(self):
        self2 = self
        class Nest(object):
            def __init__(self):
                pass
            def __enter__(self):
                self2.inclev()
            def __exit__(self, exc_type, exc_value, traceback):
                self2.declev()
        return Nest

# Manually increase/decrease level
my_instance = MyClass()
print(my_instance.level)
my_instance.inclev()
print(my_instance.level)
my_instance.inclev()
print(my_instance.level)
my_instance.declev()
print(my_instance.level)
my_instance.declev()
print(my_instance.level)

# Use instance-specific context manager
other_instance = MyClass()
print(other_instance.level)
with other_instance.Nest():
    print(other_instance.level)
    with other_instance.Nest():
        print(other_instance.level)
    print(other_instance.level)
print(other_instance.level)

Tags: 方法instanceselfmydefcontextmyclassmanager
1条回答
网友
1楼 · 发布于 2024-04-20 01:07:25

为什么需要嵌套类?只需让主对象直接实现上下文管理协议:

class MyClass(object):
    def __init__(self):
        self.level = 0
    def inclev(self):
        self.level += 1
    def declev(self):
        self.level -= 1

    __enter__ = inclev  # For __enter__, just alias inclev, no need for wrapper
    def __exit__(self, exc_type, exc_value, traceback):
        self.declev()

然后只需将其与:

^{2}$

如果您确实需要将上下文管理器协议作为一个名为Nest的构造物,您仍然可以使用contextlib中的内置函数来简化一点:

from contextlib import contextmanager

class MyClass(object):
    def __init__(self):
        self.level = 0
    def inclev(self):
        self.level += 1
    def declev(self):
        self.level -= 1

    @contextmanager
    def Nest(self):
        self.inclev()
        try:
            yield
        finally:
            self.declev()

相关问题 更多 >