如何在__init__期间调用异常__exit__方法?

qww*_*wwq 5 python python-2.7

假设你有一个定义的类__enter____exit__类似的方法:

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass
Run Code Online (Sandbox Code Playgroud)

如果在with块内引发异常,如下所示:

with MyClass() as ins:
    ins.f()
Run Code Online (Sandbox Code Playgroud)

__exit__方法将被隐式调用,这是非常好的.

但是如果你的班级是这样的:

class MyClass:
    def __init__(self):
        self.f()
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass
Run Code Online (Sandbox Code Playgroud)

你像这样实例化它:

with MyClass() as ins:
    pass
Run Code Online (Sandbox Code Playgroud)

当在__init__方法内部引发异常时,__enter__还没有被调用,并且也没有被调用__exit__,这不是那么好.解决这个问题的最佳方法是什么?

Joc*_*zel 5

显然,您不能使用无法作为上下文管理器启动的类,因此您必须先创建实例,然后才能在with块中使用该实例。

例如:

try:
    ins = MyClass()
except Exception as e: 
    print "Cant initiate MyClass"
else:
    with ins:
        pass
Run Code Online (Sandbox Code Playgroud)

您可以通过将额外的资源传递给Class而不是在初始化时创建它们来添加额外的资源:

with spawnResource() as res, MyClass(res) as y:
    print x,y
Run Code Online (Sandbox Code Playgroud)