5

假设您有一个定义了方法的类,__enter__如下__exit__所示:

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass

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

with MyClass() as ins:
    ins.f()

__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

你像这样实例化它:

with MyClass() as ins:
    pass

当在__init__方法内部引发异常时,__enter__尚未调用,并且也未调用__exit__,这不太好。解决此问题的最佳方法是什么?

4

2 回答 2

5

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

例如:

try:
    ins = MyClass()
except Exception as e: 
    print "Cant initiate MyClass"
else:
    with ins:
        pass

您可以通过将它们传递给类来添加额外的资源,而不是在启动期间创建它们:

with spawnResource() as res, MyClass(res) as y:
    print x,y
于 2013-07-01T20:08:23.437 回答
2

就像其他人指出的那样,没有干净的方法,因为您尝试做的事情很尴尬。

直接的方法是:

如果您想在 中清理某些内容,请在 中__exit__对其进行初始化 __enter__

例如

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self):
        print 'in __enter__'
        # acquire it here...
        return self
    def __exit__(self, type, value, traceback):
        print 'in __exit__'
        # release it here...

with MyClass() as ins:
    print 'calling f()'
    ins.f()
于 2013-07-01T20:36:07.773 回答