|
14 | 14 |
|
15 | 15 | 如果把它作为一个概念来阐述,似乎有点多余,因为从字面上也可以有一丝的体会,但是,我要说的是,那点直觉的体会不一定等于理性的严格定义,特别是周遭事物越来越复杂的时候。
|
16 | 16 |
|
17 |
| -“上下文”的英文是context,在网上检索了一下关于“上下文”的说法,发现没有什么严格的定义,另外,不同的语言环境,对“上下文管理”有不同的说法。根据我个人的经验和能看到的某些资料,我以为可以把“上下文”理解为某一些语句构成的一个环境(也可以说是代码块),所谓“管理”就是要在这个环境中做一些事情,做什么事情呢?就Python而言,是要将前面某个语句(“上文”)干的事情独立成为对象,然后在后面(“下文”)中使用这个对象来做事情。 |
| 17 | +“上下文”的英文是context,在网上检索了一下关于“上下文”的说法,发现没有什么严格的定义,另外,不同的语言环境,对“上下文管理”有不同的说法。根据我个人的经验和能看到的某些资料,窃以为可以把“上下文”理解为某一些语句构成的一个环境(也可以说是代码块),所谓“管理”就是要在这个环境中做一些事情,做什么事情呢?就Python而言,是要将前面某个语句(“上文”)干的事情独立成为对象,然后在后面(“下文”)中使用这个对象来做事情。 |
18 | 18 |
|
19 | 19 | **上下文管理协议**
|
20 | 20 |
|
|
32 | 32 |
|
33 | 33 | >>> name = "laoqi"
|
34 | 34 | >>> if name == "laoqi":
|
35 |
| - ... print name |
| 35 | + ... print name #Python 3: print(name) |
36 | 36 | ...
|
37 | 37 | laoqi
|
38 | 38 | >>> if name == "laoqi":
|
39 | 39 | ... for i in name:
|
40 |
| - ... print i, |
| 40 | + ... print i, #Python 3: print(i, end=',') |
41 | 41 | ...
|
42 | 42 | l a o q i
|
43 | 43 |
|
|
72 | 72 |
|
73 | 73 | 然后写出下面的代码,实现上述目的:
|
74 | 74 |
|
75 |
| - |
76 | 75 | #!/usr/bin/env python
|
77 | 76 | # coding=utf-8
|
78 | 77 |
|
|
97 | 96 |
|
98 | 97 | 可见上下文管理器是必要的,因为它让代码优雅了,当然优雅只是表象,还有更深层次的含义,继续阅读下面的内容能有深入体会。
|
99 | 98 |
|
100 |
| -**更深入** |
| 99 | +##深入理解 |
101 | 100 |
|
102 | 101 | 前面已经说了,上下文管理器执行了`__enter__()`和`__exit__()`方法,可是在`with`语句中哪里看到了这两个方法呢?
|
103 | 102 |
|
104 | 103 | 为了解把这个问题解释清楚,需要先做点别的操作,虽然工程中一般不需要做。
|
105 | 104 |
|
106 |
| - |
107 | 105 | #!/usr/bin/env python
|
108 | 106 | # coding=utf-8
|
109 | 107 |
|
110 | 108 | class ContextManagerOpenDemo(object):
|
111 | 109 |
|
112 | 110 | def __enter__(self):
|
113 |
| - print "Starting the Manager." |
| 111 | + print "Starting the Manager." #Python 3: print("Starting the Manager.") |
114 | 112 |
|
115 | 113 | def __exit__(self, *others):
|
116 |
| - print "Exiting the Manager." |
| 114 | + print "Exiting the Manager." #Python 3: print("Exiting the Manager.") |
117 | 115 |
|
118 | 116 | with ContextManagerOpenDemo():
|
119 |
| - print "In the Manager." |
| 117 | + print "In the Manager." #Python 3: print("In the Manager.") |
120 | 118 |
|
121 | 119 | 在上面的代码示例中,我们写了一个类`ContextManagerOpenDemo()`,你就把它理解为我自己写的`Open()`吧,当然使最简版本了。在这个类中,`__enter__()`方法和`__exit__()`方法都比较简单,就是要检测是否执行该方法。
|
122 | 120 |
|
|
142 | 140 | self.mode = mode
|
143 | 141 |
|
144 | 142 | def __enter__(self):
|
145 |
| - print "Starting the Manager." |
| 143 | + print "Starting the Manager." #Python 3: print("Starting the Manager.") |
146 | 144 | self.open_file = open(self.filename, self.mode)
|
147 | 145 | return self.open_file
|
148 | 146 |
|
149 | 147 | def __exit__(self, *others):
|
150 | 148 | self.open_file.close()
|
151 |
| - print "Exiting the Manager." |
| 149 | + print "Exiting the Manager." #Python 3: print("Exiting the Manager.") |
152 | 150 |
|
153 | 151 | with ContextManagerOpenDemo("23501.txt", 'r') as reader:
|
154 |
| - print "In the Manager." |
| 152 | + print "In the Manager." #Python 3: print("In the Manager.") |
155 | 153 | for line in reader:
|
156 |
| - print line |
| 154 | + print line #Python 3: print(line) |
157 | 155 |
|
158 | 156 | 这段代码的意图主要是:
|
159 | 157 |
|
|
173 | 171 |
|
174 | 172 | Exiting the Manager.
|
175 | 173 |
|
176 |
| -在上述代码中,我们没有对异常进行处理,也就是把异常隐藏了,不管在代码块执行时候遇到什么异常,都是要离开代码块,那么就立刻让`__exit__()`方法接管了。 |
| 174 | +在上述代码中,我们没有显示地写捕获异常的语句,不管在代码块执行时候遇到什么异常,都是要离开代码块,那么就立刻让`__exit__()`方法接管了。 |
177 | 175 |
|
178 | 176 | 如果要把异常显现出来,也使可以,可以改写`__exit__()`方法。例如:
|
179 | 177 |
|
@@ -206,7 +204,7 @@ Python中的这个模块使上下文管理中非常好用的东东,这也是
|
206 | 204 |
|
207 | 205 | ###contextlib.closing()
|
208 | 206 |
|
209 |
| -要想知道`contextlib.closing()`的使用方法,最常用的方法就是`help()`,这是我们的一贯做法,胜过查阅其它任何资料。 |
| 207 | +要想知道`contextlib.closing()`的使用方法,最常用的方法就是`help()`,这是我们的一贯做法。 |
210 | 208 |
|
211 | 209 | Help on class closing in module contextlib:
|
212 | 210 |
|
@@ -260,13 +258,15 @@ contextlib.contextmanager是一个装饰器,它作用于生成器函数(也
|
260 | 258 |
|
261 | 259 | @contextmanager
|
262 | 260 | def demo():
|
263 |
| - print "before yield." |
| 261 | + print "before yield." |
264 | 262 | yield "contextmanager demo."
|
265 | 263 | print "after yield."
|
266 | 264 |
|
267 | 265 | with demo() as dd:
|
268 | 266 | print "the word is: %s" % dd
|
269 | 267 |
|
| 268 | +尊重引用的文章,所以上述代码就不再注释Python 3下如何修改了。如果读者是使用Python 3的,可以自行将代码中的`print`语句修改为`print()`函数式样。 |
| 269 | + |
270 | 270 | 运行结果是:
|
271 | 271 |
|
272 | 272 | $ python 23504.py
|
|
0 commit comments