Python 与语句
我正在尝试使用 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
语句中做错了什么,有效地手动调用了构造函数。我该如何纠正这个问题?
I'm experimenting with Python's with
statements, and I've found that in the following code listing my __init__
method gets called twice, while my __exit__
method gets called once. This presumably means that there will be a resource leak if this code did anything useful.
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()
This is the program's output:
Constructing MyResource
Entering MyResource
Constructing MyResource
Some function
Cleaning up MyResource
I'm guessing it's because I'm doing something wrong in the with
statement, effectively calling the constructor manually. How do I correct this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您不应从 __enter__ 返回新实例。相反,返回
self
(正在调用__enter__
的实例。这就是为什么__init__()
被调用两次——你调用它两次,一次在 with 语句中,一次在__enter__()
中,这是正确的版本:You shouldn't return a new instance from
__enter__
. Instead, returnself
(the instance for which__enter__
is being called. That's why__init__()
is called twice -- you call it twice, once in your with statement, once in__enter__()
. Here's a correct version:__init__
被调用两次的原因是因为您调用了它两次:一次是在
with
语句中启动MyResource
对象时,另一次是在with
语句调用__enter__
,后者创建并返回MyResource
的不同实例。您的
__enter__
方法应返回 <代码>自我代替。The reason
__init__
is being invoked twice is since you call it twice:Once when you initiate a
MyResource
object in thewith
statement and once more when thewith
statement invokes__enter__
which in turn creates and returns a different instance ofMyResource
Your
__enter__
method should returnself
instead.我的猜测是,您不会返回 MyResource() 而是返回 self,因为 self 是已构造类的实例。
My guess is that you do not
return MyResource()
butreturn self
, asself
is the instance of the already constructed class.将代码更改为:
__enter__
方法用于进行初始化,而不是创建实例,它已经存在(自身)。Change your code to:
The
__enter__
method is there for you to do initialization, not to create your instance, it already exists (self).