Module 模块
一般来说,如果你的工程在一个脚本文件中就能写完搞定,那么就不用搞module这种概念, module主要是为了一个相对比较大的工程,涉及到多个文件之间的互相调用关系。 如果一个文件写所有的代码可能成千上万行,阅读起来一点也不友善, 所以我们更长是将大项目的长代码拆开成多个模块,用文件夹和多文件的方式管理起来,方便后期维护。 这就有了 module 模块的程序代码管理方式。
我给大家先看一下,莫烦Python这个网页的一些代码架构吧,在做这个网页代码架构的时候,我无时无刻都使用这 module 模块的概念。
本次的练习代码,因为是在浏览器中演练的,所以有些操作还是和实际开发Python项目有偏差。 我会在具体有偏差的地方给大家说明。
文件中的代码¶
还是我们的大背景,如果我们要设定一个文件管理系统,这个系统中肯定有很多功能,有文件查找,文件修改,权限管理等等。 每一个可以被分类的功能都可以被放在特定的一个组里。我们就从最简单的module说起。
假设我写好了一些功能,这些功能可以被其他人使用。 我是直接给一段代码给别人使用呢,还是给一个Python文件?我还是喜欢给文件的,因为不管你写了什么代码, 你给我个文件,我对你的代码就无感知,我只需要按照功能从你的文件中调取出来特定功能就好了。 比如有人给了我一份 file.py
文件。这个文件里有 create_name()
的功能。
作为这个功能的使用者,我不关心你 create_name()
里面的代码是怎么实现的,我只关心我可以用 create_name()
这个功能就好。
注意,在这个教学中,我已经提前为了在你的浏览器里临时创建一个 file.py
文件,我们后面就可以调用起来了。 如果在你本地实验的话,也就相当于下面截图的意思。
引用 module¶
引用 module,我们通常也可以说成 引用库,引用包,引用代码 等。总之就是引用一份已经写好的代码。 创建好 file.py
后,相当于别人给了你一个可被调用的文件后,我们怎么引用呢?
当然,我们得有自己的一个 .py
文件,我就假设自己的这个Python文件叫做 me.py
吧。 所以你可以在同目录下,创建一个 me.py
并把这面这段代码写在你的 me.py
中。
你点运行,就会发现,它能打印出你在 file.py
里定义的那个 new_file.txt
名字,这就证明我们能成功引用之前写的功能了。 也就意味着,我们引用 file.py
这个文件的写法是 import file
。 而调用 file.py
里的 create_name()
的写法是 file.create_name()
。熟悉 Python Class 的同学可能会立马发现。 这里调用模块功能的时候和调用Python类功能更有异曲同工之处。甚至下面我们换一种方式,你会觉得更像了。
你看,这两种用法简直了!一模一样,当我给 file
重命名时, import file as f1
,就和 f2 = File()
简直一模一样,他俩你目前可以想是等价的。 然后使用它们的 create_name()
功能呢的方式也一模一样。
长得像不是没有原因的,因为module的设计真的可以和class一模一样,我们在后面会继续讲到。
上面在写 import file as f1
无意间,我就透露了另一个知识点,你可以给模块重命名的。好,接下来我们再多说几种引用的方式。
如果你的 file.py
里面有多个函数,你也可以一起写在 import
里。
如果函数真的很多,而且你也不想一一写出来,你可以有两种方式来达成简化的目的,前一种已经介绍了,后一种是新的方式。
大项目的模块管理¶
在稍微大点的项目中,随着代码量增加,代码管理起来越来越困难。很多时候我都不知道要去哪找代码。 所以优秀的代码框架,好的模块定义成了增加开发效率的关键。比如这个文件管理系统,我再做一个架构,搞一下功能分区。
注意,这里用的依赖文件和文件夹,我也帮你提前悄悄
在浏览器缓存中创建了。 对应到本地文件的结构的话,其实就和上面截图一致。
上面刚开始讲解的时候我们不是提了一嘴 module 和 class 很像嘛, 现在我们就来看看到底有多像。
正规的 module 中,我们常会看到一个 __init__.py
文件,这个文件其实就有点像 class 里的 def __init__(self)
, 你可以在里面写上要如何初始化你的 files
目录。也可以设定目录中个元素的关系。
我在 __init__.py
中写下了下面这段话,待会我们来演示一下这段话的作用。 注意,下面这段代码,你不要点击运行按钮。点击了会报错的。
设置好 __init__.py
后,我们就能直接从 files
里 import get_video_size
这个属于 video.py
的功能了。
但是和 video.py
同级的 text.py
就无法通过这种 import 方式获取到 text.py
的功能。
如果我们要获取到 text.py
的功能,我们得这样 import:
好了,更复杂的代码,有更复杂的结构,不过也都是一层层嵌套上面这样的做法。有了这些基础,我相信你遇到大项目的时候, 应该都能迎刃而解。