在 Python2.5 里引入了一个新关键字(with)使得一个新方法得到了代码复用。 上下文管理这个概念在 Python 中早已不是新鲜事了(之前它作为库的一部分被实现过),但直到 PEP343 才作为第一个类语言结构取得了重要地位而被接受。 你有可能早就已经见识过 with 声明:
with open('foo.txt') as bar: # 对bar执行某些动作
上下文管理允许对对象进行设置和清理动作,用 with 声明进行已经封装的操作。 上下文操作的行为取决于 2 个神奇方法:
__enter__(self)
定义块用 with 声明创建出来时上下文管理应该在块开始做什么。 注意,__enter__ 的返回值必须绑定 with 声明的目标,或是 as 后面的名称。
__exit__(self, exception_type, exception_value, traceback)
定义在块执行(或终止)之后上下文管理应该做什么。 它可以用来处理异常,进行清理,或行动处于块之后某些总是被立即处理的事。 如果块执行成功的话,excepteion_type,exception_value,和 traceback 将会置None。 否则,你可以选择去处理异常,或者让用户自己去处理。 如果你想处理,确保在全部都完成之后__exit__ 会返回 True。 如果你不想让上下文管理处理异常,那就让它发生好了。
__enter__ 和 __exit__ 对那些已有良好定义和对设置,清理行为有共同行为的特殊类是有用。 你也可以使用这些方法去创建封装其他对象通用的上下文管理。 看下面的例子:
class Closer: '''用with声明一个上下文管理用一个close方法自动关闭一个对象''' def __init__(self, obj): self.obj = obj def __enter__(self): return self.obj # 绑定目标 def __exit__(self, exception_type, exception_val, trace): try: self.obj.close() except AttributeError: #obj不具备close print 'Not closable.' return True # 成功处理异常
以下是一个对于 Closer 实际应用的一个例子,使用一个 FTP 连接进行的演示(一个可关闭的套接字):
>>> from magicmethods import Closer >>> from ftplib import :;; >>> with Closer(FTP('ftp.somsite.com')) as conn: ... conn.dir() ... # 省略的输出 >>> conn.dir() # 一个很长的AttributeError消息, 不能关闭使用的一个连接 >>> with Closer(int(5)) as i: ... i += 1 ... Not closeable. >>> i 6
瞧见我们如何漂亮地封装处理正确或不正确的用例了吗?那就是上下文管理和神奇方法的威力。
暂无评论
写评论