码迷,mamicode.com
首页 > 其他好文 > 详细

with: __enter__ and __exit__

时间:2015-07-30 16:48:13      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

要使我们的对象支持with语句,必须为它实现 __enter____exit__方法。

先看一个例子:

from socket import socket, AF_INET, type=SOCK_STREAM

class lazyConnection:
    def __init__(self, address, family=AF_INET,         type=SOCK_STREAM):
        self.address = address
        self.family = AF_INET
        self.type = SOCK_STREAM
        self.sock = None

    def __enter__(self):
        if self.sock is not None:
            raise RuntimeError(‘already connected‘)
        self.sock = socket(self.family, 
            self.type)
        self.sock.connect(self.address)
        return self.sock

    def __exit__(self, exc_ty, exc_val, tb):
        self.sock.close()
        self.sock = None

例子中的类是一个网络连接类,但是他在初始化的时候 并没有真正建立连接,而是在使用with语句的时候才 建立连接,所以是惰性lazy的,eg

from functools import partial

conn = LazyConnection(
    (‘www.python.org‘, 80)
)

with conn as s:
    # conn.__enter__() exec, connection open
    s.send(b‘GET /index.html HTTP/1.0\r\n‘)
    s.send(‘Host: www.python.org\r\n‘)
    s.send(‘\r\n‘)
    resp = b‘‘.join(iter(partial(s.recv, 8192),
        b‘‘))

    # conn.__exit__() exec, connection close

使用with语句的时候,会触发__enter__函数, 函数的返回值会赋值给with as后面的标识符。 然后就会执行with的body,完成后触发__exit__函数

实际中使用with更多的情况是操作一些资源如文件, 网络连接,锁等。因为这些资源要显式的打开和关闭 ,如果忘记关闭容易引起问题,所以这种情况使用with 比较好。

with: __enter__ and __exit__

标签:

原文地址:http://www.cnblogs.com/jolin123/p/4689589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!