|
4 | 4 | "cell_type": "markdown",
|
5 | 5 | "metadata": {},
|
6 | 6 | "source": [
|
7 |
| - "# 模块的创建 \n", |
| 7 | + "# 1. 模块的创建 \n", |
8 | 8 | "定义模块,只要使用文本编辑器,把一些 Python 代码输入至文本文件中,然后以“.py”为后缀名进行保存,任何此类文件都会被自动认为是 Python 模块。在模块顶层指定的所有变量名都会变成其属性,并且可以导出供客户端来使用。 \n",
|
9 | 9 | "\n",
|
10 | 10 | "例如,如果在名为 module1.py 的文件中输入下面的 def 语句,并将这个文件导入,就会创建一个拥有一个属性的模块对象。"
|
|
24 | 24 | "cell_type": "markdown",
|
25 | 25 | "metadata": {},
|
26 | 26 | "source": [
|
27 |
| - "## 模块文件名 \n", |
| 27 | + "## 1.1 模块文件名 \n", |
28 | 28 | "模块名在 Python 程序中会变成变量名(没有.py)。当一个模块被导入时,Python 会把内部模块名映射到外部文件名,也就是说通过把模块搜索路径中的目录路径加在前边,而 .py 或其他后缀名添加在后边。 \n",
|
29 | 29 | "\n",
|
30 |
| - "# 模块的使用 \n", |
| 30 | + "# 2. 模块的使用 \n", |
31 | 31 | "客户端可以执行 import 或 from 语句。import 会读取整个模块,所以必须进行定义后才能读取它的变量名;from 将获取(或者说复制)模块特定的变量名。 \n",
|
32 | 32 | "\n",
|
33 |
| - "## import 语句 \n", |
| 33 | + "## 2.1 import 语句 \n", |
34 | 34 | "上面的变量名 module1 有两个不同的目的:识别要被载入的外部文件,同时会生成脚本中的变量,在文件加载后,用来引用模块对象。"
|
35 | 35 | ]
|
36 | 36 | },
|
|
63 | 63 | "cell_type": "markdown",
|
64 | 64 | "metadata": {},
|
65 | 65 | "source": [
|
66 |
| - "## from 语句 \n", |
| 66 | + "## 2.2 from 语句 \n", |
67 | 67 | "因为 from 会把变量名复制到另一个作用域,所以它就可以让我们直接在脚本中使用复制后的变量名,而不需要通过模块。"
|
68 | 68 | ]
|
69 | 69 | },
|
|
89 | 89 | "cell_type": "markdown",
|
90 | 90 | "metadata": {},
|
91 | 91 | "source": [
|
92 |
| - "## from * 语句 \n", |
| 92 | + "## 2.3 from * 语句 \n", |
93 | 93 | "当我们使用 * 时,会取得模块顶层所有赋了值的变量名的拷贝。还是在脚本中使用复制后得到的变量名 printer,而不需要通过模块名。"
|
94 | 94 | ]
|
95 | 95 | },
|
|
115 | 115 | "cell_type": "markdown",
|
116 | 116 | "metadata": {},
|
117 | 117 | "source": [
|
118 |
| - "## 导入只发生一次 \n", |
| 118 | + "## 2.4 导入只发生一次 \n", |
119 | 119 | "模块会在第一次 import 或 from 时载入并执行,并且只在第一次如此。之后的导入操作都只会取出已加载的模块对象。 \n",
|
120 | 120 | "\n",
|
121 | 121 | "**初始化代码**"
|
|
182 | 182 | "cell_type": "markdown",
|
183 | 183 | "metadata": {},
|
184 | 184 | "source": [
|
185 |
| - "## import 和 from 是赋值语句 \n", |
| 185 | + "## 2.5 import 和 from 是赋值语句 \n", |
186 | 186 | "import 和 from 是可执行的语句,可以嵌套在 if 测试中,出现在函数 def、try 语句之中等。 \n",
|
187 | 187 | "\n",
|
188 | 188 | "import 和 from 都是隐形的赋值语句:\n",
|
|
194 | 194 | "cell_type": "markdown",
|
195 | 195 | "metadata": {},
|
196 | 196 | "source": [
|
197 |
| - "## import 和 from 的对等性 \n", |
| 197 | + "## 2.6 import 和 from 的对等性 \n", |
198 | 198 | "一个像这样的 from 语句:\n",
|
199 | 199 | "```\n",
|
200 | 200 | "from module import name1, name2\n",
|
|
212 | 212 | "cell_type": "markdown",
|
213 | 213 | "metadata": {},
|
214 | 214 | "source": [
|
215 |
| - "# 模块命名空间 \n", |
216 |
| - "## 文件生成命名空间 \n", |
| 215 | + "# 3. 模块命名空间 \n", |
| 216 | + "## 3.1 文件生成命名空间 \n", |
217 | 217 | "- **模块语句会在首次导入时执行。**\n",
|
218 | 218 | "- **顶层的赋值语句会创建模块属性。**\n",
|
219 | 219 | "- **模块的命名空间能通过属性 `__dict__` 或 dir(M) 获取。**\n",
|
220 | 220 | "- **模块是一个独立的作用域(本地变量就是全局变量)。**\n",
|
221 | 221 | "\n",
|
222 |
| - "## 命名空间字典:`__dict__` \n", |
| 222 | + "## 3.2 命名空间字典:`__dict__` \n", |
223 | 223 | "在内部模块命名空间是作为字典对象进行存储的。可以通过模块的 `__dict__` 属性获取模块命名空间字典:"
|
224 | 224 | ]
|
225 | 225 | },
|
|
255 | 255 | "cell_type": "markdown",
|
256 | 256 | "metadata": {},
|
257 | 257 | "source": [
|
258 |
| - "## 属性名的点号运算 \n", |
| 258 | + "## 3.3 属性名的点号运算 \n", |
259 | 259 | "在 Python 中,可以使用点号运算语法 object.attribute 获取任意 object 的 attribute 属性。 \n",
|
260 | 260 | "\n",
|
261 | 261 | "属性的点号运算与作用域法则无关,LEGB 规则只适用于无点号运算的纯变量名。以下是其规则:\n",
|
|
264 | 264 | "- **多层点号运算。**X.Y.Z 指的是寻找对象 X 之中的变量名 Y,然后再找对象 X.Y 之中的 Z。\n",
|
265 | 265 | "- **通用性。**点号运算可用于任何具有属性的对象:模块、类、C 扩展类型等。\n",
|
266 | 266 | "\n",
|
267 |
| - "## 导入和作用域 \n", |
| 267 | + "## 3.4 导入和作用域 \n", |
268 | 268 | "导入操作不会赋予被导入文件中的代码对上层代码的可见度:被导入文件无法看见进行导入的文件内的变量名。更确切的说法是:\n",
|
269 | 269 | "- 函数绝对无法看见其他函数内的变量名,除非它们从物理上处于这个函数内。\n",
|
270 | 270 | "- 模块程序代码绝对无法看见其他模块内的变量名,除非明确地进行了导入。\n",
|
|
276 | 276 | "cell_type": "markdown",
|
277 | 277 | "metadata": {},
|
278 | 278 | "source": [
|
279 |
| - "# 重载模块 \n", |
| 279 | + "# 4. 重载模块 \n", |
280 | 280 | "调用 reload 内置函数可以强制使模块代码重新载入并重新运行。此文件中新的代码的赋值语句会在适当的地方修改现有的模块对象。 \n",
|
281 | 281 | "\n",
|
282 | 282 | "reload 函数可以修改程序的一些部分,而无需停止整个程序。因此,利用 reload,可以立即看到对组件的修改的效果。 \n",
|
283 | 283 | "\n",
|
284 | 284 | "在 Python 3.X 中,reload 在 imp 标准库模块中,需要 import 语句或 from 语句来载入该工具。 \n",
|
285 | 285 | "\n",
|
286 |
| - "## reload 基础 \n", |
| 286 | + "## 4.1 reload 基础 \n", |
287 | 287 | "- reload 是 Python 中的内置函数,而不是语句。\n",
|
288 | 288 | "- 传给 reload 的是已经存在的模块对象,而不是变量名。\n",
|
289 | 289 | "- reload 在 Python 3.X 中位于模块中,并且必须导入自己。\n",
|
|
305 | 305 | "- **重载只会对以后使用 from 的客户端造成影响。**\n",
|
306 | 306 | "- **重载只应用于单个模块。** \n",
|
307 | 307 | "\n",
|
308 |
| - "## reload 实例 \n", |
| 308 | + "## 4.2 reload 实例 \n", |
309 | 309 | "下面,我们要修改并重载一个模块文件,但不会中止交互模式的 Python 会话。 \n",
|
310 | 310 | "\n",
|
311 | 311 | "首先,在文本编辑器中,编写一个名为 changer.py 的模块文件,其内容如下:"
|
|
445 | 445 | "name": "python",
|
446 | 446 | "nbconvert_exporter": "python",
|
447 | 447 | "pygments_lexer": "ipython3",
|
448 |
| - "version": "3.6.5" |
| 448 | + "version": "3.6.8" |
449 | 449 | }
|
450 | 450 | },
|
451 | 451 | "nbformat": 4,
|
|
0 commit comments