Python 与语句

发布于 2024-12-01 00:17:49 字数 833 浏览 0 评论 0原文

我正在尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

终难遇 2024-12-08 00:17:49

您不应从 __enter__ 返回新实例。相反,返回 self (正在调用 __enter__ 的实例。这就是为什么 __init__() 被调用两次——你调用它两次,一次在 with 语句中,一次在 __enter__() 中,这是正确的版本:

def __enter__(self):
    print 'Entering MyResource'
    return self

You shouldn't return a new instance from __enter__. Instead, return self (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:

def __enter__(self):
    print 'Entering MyResource'
    return self
微凉徒眸意 2024-12-08 00:17:49

__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 the with statement and once more when the with statement invokes __enter__ which in turn creates and returns a different instance of MyResource

Your __enter__ method should return self instead.

蓝天白云 2024-12-08 00:17:49

我的猜测是,您不会返回 MyResource() 而是返回 self,因为 self 是已构造类的实例。

My guess is that you do not return MyResource() but return self, as self is the instance of the already constructed class.

神爱温柔 2024-12-08 00:17:49

将代码更改为:

def __enter__(self):
    print 'Entering MyResource'
    return self

__enter__ 方法用于进行初始化,而不是创建实例,它已经存在(自身)。

Change your code to:

def __enter__(self):
    print 'Entering MyResource'
    return self

The __enter__ method is there for you to do initialization, not to create your instance, it already exists (self).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文