Skip to content

Commit d72c8bf

Browse files
committed
2.4.2
1 parent b095237 commit d72c8bf

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

2.4.md

+26
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,31 @@
101101

102102
**实践指南。**通过引入`nonlocal`语句,我们创建了复制语句的双重作用。它们修改了局部绑定,或者修改非局部绑定。实际上,赋值语句已经有了两个作用:创建新的绑定,或者重新绑定现有名称。Python 赋值的许多作用使赋值语句的执行效果变得模糊。作为一个程序员,你应该用文档清晰记录你的代码,使赋值的效果可被其它人理解。
103103

104+
## 2.4.2 非局部赋值的好处
104105

106+
非局部赋值是将程序作为独立和自主的对象观察的重要步骤,对象彼此交互,但是各自管理各自的内部状态。
105107

108+
特别地,非局部赋值提供了在函数的局部范围中维护一些状态的能力,这些状态会在函数之后的调用中演化。和特定`withdraw`函数相关的`balance`在所有该函数的调用中共享。但是,`withdraw`实例中的`balance`绑定对程序的其余部分不可见。只有`withdraw`关联到了`make_withdraw`的帧,`withdraw`在那里被定义。如果`make_withdraw`再次调用,它会创建单独的帧,带有单独的`balance`绑定。
109+
110+
我们可以继续以我们的例子来展示这个观点。`make_withdraw`的第二个调用返回了第二个`withdraw`函数,它关联到了另一个环境上。
111+
112+
```py
113+
>>> wd2 = make_withdraw(7)
114+
```
115+
116+
第二个`withdraw`函数绑定到了全局帧的名称`wd2`上。我们使用星号来省略了表示这个绑定的线。现在,我们看到实际上有两个`balance`的绑定。名称`wd`仍旧绑定到余额为`12``withdraw`函数上,而`wd2`绑定到了余额为`7`的新的`withdraw`函数上。
117+
118+
![](img/nonlocal_def2.png)
119+
120+
最后,我们调用第二个绑定到`wd2`上的`withdraw`函数:
121+
122+
```py
123+
>>> wd2(6)
124+
1
125+
```
126+
127+
这个调用修改了非局部名称`balance`的绑定,但是不影响在全局帧中绑定到名称`wd`的第一个`withdraw`
128+
129+
![](img/nonlocal_call2.png)
130+
131+
这样,`withdraw`的每个实例都维护它自己的余额状态,但是这个状态对程序中其它函数不可见。在更高层面上观察这个情况,我们创建了银行账户的抽象,它管理自己的内部状态,但以一种方式对真实世界的账户进行建模:它基于自己的历史提取请求来随时间变化。

img/nonlocal_call2.png

103 KB
Loading

img/nonlocal_def2.png

101 KB
Loading

0 commit comments

Comments
 (0)