第 25 章 高级模块主题 高级模块主题
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
在本章的最后,我们将介绍更多与模块相关的高级主题--数据隐藏、__future__ 模块、__name__ 变量、sys.path 更改、列表工具、按名称字符串导入模块、传递重载等,同时还将介绍与本部分内容相关的标准疑难解答和练习。
在此过程中,我们将结合函数和模块,构建一些比目前的工具更大、更有用的工具。与函数一样,如果模块的接口定义得好,它们就会更有效,因此本章也简要回顾了模块设计概念,我们在前面的章节中已经探讨过其中的一些概念。
尽管本章标题中使用了 "高级 "一词来表示对称性,但这主要是一个附加模块主题的大杂烩。由于这里讨论的一些主题应用广泛,尤其是__name__ 技巧,因此在继续学习本书下一部分的课程之前,请务必先浏览这里。
模块设计概念
与函数一样,模块也会带来设计上的权衡:你必须考虑哪些函数放在哪些模块中,模块的通信机制,等等。 当你开始编写更大的 Python 系统时,所有这些都会变得更加清晰,但这里有一些一般的想法需要牢记:
在 Python中,你总是在一个模块中。不可能写出不在某个模块中的代码。正如第 17 章和第 21 章中简要提到的,即使是在交互式提示符下输入的代码,实际上也是在一个叫做
__main__的内置模块中;交互式提示符的唯一独特之处在于,代码运行后会立即丢弃,表达式的结果会自动打印出来。尽量减少模块耦合:全局变量。与函数一样, 模块的最佳编写方式也是封闭式。根据经验,除了从模块导入的函数和类之外,模块应尽可能独立于其他模块中使用的全局变量。模块应与外部世界共享的唯一东西就是它所使用的工具和它所定义的工具。
最大化模块内聚力:统一目的。通过最大限度地提高模块的内聚力,可以最大限度地减少模块的耦合;如果模块的所有组件都有一个共同的目的,就不太可能依赖外部名称。
模块很少应该更改其他模块的变量。我们在第 17 章中用代码说明了这一点,但在此值得重申:使用其他模块中定义的全局变量是完全没问题的(毕竟这就是客户端导入服务的方式),但更改其他模块中的全局变量通常是设计问题的表现。当然也有例外情况,但你应该尽量通过函数参数和返回值等设备来交流结果,而不是跨模块更改。否则,你的全局项的值就会依赖于其他文件中任意远程赋值的顺序,你的模块就会变得更难理解和重用。
图 25-1概括了模块的运行环境。模块包含变量、函数、类和其他模块(如果已导入)。函数有自己的局部变量,类也是如此--类是模块中的对象,我们将在下一章开始学习。正如我们在第四部分中看到的,函数也可以嵌套,但最终都被顶部的模块所包含。

图 25-1. 模块执行环境。模块是被导入的,但模块也会导入和使用其他模块,这些模块可能是用 Python 或其他语言(如 C 语言)编写的。模块又包含变量、函数和类来完成它们的工作,它们的函数和类可能包含变量和它们自己的其他项目。不过,从顶层来看,程序只是模块的集合。
模块中的数据隐藏
正如我们所看到的,一个 Python 模块会导出在其文件顶层分配的所有名称。没有声明哪些名称应该或不应该在模块外可见的概念。事实上,如果客户端想改变模块内部的名称,也没有办法阻止。
在 Python 中,模块中的数据隐藏是一种惯例,而不是语法约束。如果你想通过破坏模块名来破坏模块,你可以这么做,但幸运的是,我还没有遇到过一个以此为人生目标的程序员。一些纯粹主义者反对这种自由的数据隐藏态度,声称这意味着 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access