Python with 语句
我正在尝试使用Python的with
语句,发现下面这段代码中我的__init__
方法被调用了两次,而__exit__
方法只被调用了一次。这可能意味着如果这段代码做了什么有用的事情,就会出现资源泄漏的问题。
class MyResource:
def __enter__(self):
print 'Entering MyResource'
return MyResource()
def __exit__(self, exc_type, exc_value, traceback):
print 'Cleaning up MyResource'
def __init__(self):
print 'Constructing MyResource'
def some_function(self):
print 'Some function'
def main():
with MyResource() as r:
r.some_function()
if __name__=='__main__':
main()
这是程序的输出:
Constructing MyResource
Entering MyResource
Constructing MyResource
Some function
Cleaning up MyResource
我猜这可能是因为我在with
语句中做错了什么,实际上是手动调用了构造函数。我该如何修正这个问题呢?
4 个回答
3
我猜你的代码里不是在 return MyResource()
,而是在 return self
。因为 self
是已经创建好的这个类的实例。
6
之所以会调用两次 __init__
,是因为你实际上调用了两次:
第一次是在 with
语句中创建一个 MyResource
对象的时候,第二次是在 with
语句调用 __enter__
方法时,这个方法又创建并返回了一个不同的 MyResource
实例。
你的 __enter__
方法应该返回 self
,也就是当前的对象。
20
在__enter__
这个方法里,你不应该返回一个新的实例。相反,你应该返回self
,也就是调用__enter__
的那个实例。这就是为什么__init__()
会被调用两次的原因——你在使用with语句的时候调用了一次,在__enter__()
里又调用了一次。下面是一个正确的写法:
def __enter__(self):
print 'Entering MyResource'
return self