python 3中类级别的__enter__和__exit__

Ric*_*ann 3 python with-statement class-method python-3.x

我没有成功尝试获取magic with-statement方法__enter____exit__在类级别上运行:

class Spam():

    @classmethod
    def __enter__(cls):
        return cls

    @classmethod
    def __exit__(cls, typ, value, tb):
        cls.cleanup_stuff()


with Spam:
    pass
Run Code Online (Sandbox Code Playgroud)

但是,这将导致AttributeError:

Traceback (most recent call last):
  File "./test.py", line 15, in <module>
    with Spam:
AttributeError: __exit__
Run Code Online (Sandbox Code Playgroud)

是否可以在类级别使用__enter____exit__方法?

mat*_*ata 13

__enter__并且__exit__是特殊方法,因此只有在对象的类型上定义时才能正常工作,而不是在它的实例字典中.

现在Spam是一个实例type,并且type(Spam).__enter__type(Spam).__exit__不存在.因此,您会收到属性错误.

要使其工作,需要在要使用的类的元类上声明方法.例:

class Spam(type):

    def __enter__(cls):
        print('enter')
        return cls

    def __exit__(cls, typ, value, tb):
        print('exit')

class Eggs(metaclass=Spam):
    pass

with Eggs:
    pass
Run Code Online (Sandbox Code Playgroud)

现在EggsSpam(type(Eggs)== Spam,因此type(Eggs).__enter__并且type(Eggs).__exit__确实存在)的实例.

然而,定义一个元类只是为了使用它的一个实例作为上下文管理器似乎有点过头了.从您的示例开始,更直接的解决方案就是使用

with Spam():
    pass
Run Code Online (Sandbox Code Playgroud)

或者,如果您想稍后重用相同的实例:

spam = Spam()
with spam:
    pass
Run Code Online (Sandbox Code Playgroud)