Python3学习笔记 | 二十二、Python的模块-模块的宏伟蓝图

部分设备阅读本文会存在代码错乱的情况,可点击阅读原文链接到博客中进行查看

一、模块简介

模块是最高级别的程序组织单元,它将程序代码和数据封装起来以便重用。从实际角度来看,模块往往对应于Python程序文件(或是用外部语言如C、Java或C#编写而成的扩展)。每一个文件都是一个模块,并且模块导入其他模块之后就可以使用导入模块定义的变量名。模块由两个语句和一个重要的内置函数进行处理。 import:使客户端(导入者)以一个整体获取一个模块 from:允许客户端从一个模块文件中获取特定的变量名 imp.reload:在不终止Python程序的情况下,提供了一种重新载入模块文件代码的方法。

为什么使用模块

代码重用: 模块可以在文件中永久保存代码。我们可以按照需要任意次数地重新载入和重新运行模块。模块还是定义变量名的空间,被认作是属性,可以被多个外部的客户端引用。 系统命名空间的划分: 模块可以被认为是变量名的软件包。模块将变量名封装进了自包含的软件包,这样就避免变量名的冲突。要使用这些变量,不精确定位的话是看不到这些变量的。 实现共享服务和数据: 模块对实现跨系统共享的组件是很方便的,只需要一个拷贝即可。

二、Python程序架构

1、如何组织一个程序

一般来讲,一个Python程序包括了多个含有Python语句的文本文件。程序是作为一个主体的、顶层的文件来构造的,配合0个或多个支持的文件,在Python中这些文件称作模块。 在Python中顶层文件(或者称之为脚本)包含了程序的主要的控制流程:这就是你需要运行来启动应用的文件。模块文件就是工具的库,这些工具是用来收集顶层文件使用的组件。顶层文件使用了在模块文件中定义的工具,而这些模块使用了其他模块所定义的工具。 模块文件通常在运行时不需要直接做任何事。然而,它们定义的工具会在其他文件中使用。在Python中,一个文件导入了一个模块来获得这个模块定义的工具的访问权限,这些工具被认作是这个模块的属性。 附:属性可以认为是变量(函数名也算是变量)

2、导入和属性

下图中,main.py是顶层文件,part1.py和part2.py是模块。main.py是导入part1.py和part2.py,part1.py和part2.py是相互导入、而且还导入了标准库模块。我们要运行的是main.py,而通常part1.py和part2.py不会直接运行。

3、标准库模块

之前页面看到的“标准库模块”是Python自身提供的,不需要程序员编写的。 Python自带了很多实用的模块,称为标准链接库。这个集合体大约有200个模块,包含与平台不相关的常见程序设计任务:操作系统接口、对象永久保存、文字模式匹配、网络和Internet脚本、GUI建构等。 这些工具都不是Python语言的组成部分,但是,你可以在任何安装了标准Python的情况下,导入适当的模块来使用。因为这些都是标准库模块,可以理所当然地认为它们一定可以用,而且在执行Python的绝大多数平台上都可以运行。 这里,包含之前所使用过的os、sys等。这些标准库的使用方法,可以在官方网站www.python.org里查到。

三、import

1、如何工作

在Python里import与C语言等的#include有些不同。C语言是把别的代码导入进来,但在Python里,是运行一次模块的代码。Python里第一次导入指定文件时,会执行三个步骤: 1、找到模块文件 2、编译成位码(需要时) 3、执行模块的代码来创建其所定义的对象 当你导入过一次后,导入相同模块时,会跳过这三个步骤。Python把载入的模块存储到一个名为sys.modules的表中(是一个字典),并在一次导入操作的开始检查该表。如果模块不存在,将会执行三个步骤。

2、搜索

首先,Python必须查找到import语句所引用的模块文件。之前我们import part1的时候,没有写具体路径,但是程序还是能找到正确路径。事实上,我们写import的时候,只能写文件名,不能写路径的。Python使用了标准模块搜索路径来找出import语句所对应的模块文件。之后会对此说明。

>>> import part1
>>> import /tmp/part2
File "<stdin>", line 1
import /tmp/part2
^
SyntaxError: invalid syntax
>>> import part2

3、编译(可选)

在遍历模块搜索路径之后,找到符合import语句的源代码之后,如果必要的话,Python接下来会将其编译成字节码。 当发现已有字节码,并更新时间比源码新,不会生成新的字节码。但是源码更新时间比字节码新,或者没有字节码,就会生成新的字节码。当没有源码,只有字节码的时候,也可以导入。 这个编译过程,只在导入时进行。顶层文件,没有被任何代码导入过,是不会生成字节码的,其字节码只会存储在内存当中。

R:tmp tav$ ls -l | grep part1
-rw-r--r-- 1 tav wheel 90 Apr 12 19:37 part1.py
-rw-r--r-- 1 tav wheel 416 Apr 12 19:38 part1.pyc

4、运行

import的最后一步是执行模块的字节码。文件中所有语句会依次执行。此步骤中任何对变量名的赋值运算,都会产生所得到的模块文件的属性。

$ more part3.py
print('This is part3 import')
>>> import part3
This is part3 import
>>> reload(part3)
This is part3 import
<module 'part3' from 'part3.pyc'>
>>> import part3
>>>

如上所示,需要重新载入(运行)模块的话,可以使用reload。要是直接再次import的话,不会做任何操作的。

四、模块搜索路径

在导入模块的时候,最重要的部分是:定位要导入的文件。因为我们要告诉Python到何处去找到要导入的文件。在Python里,模块搜索的路径如下: 1、程序的主目录 2、PYTHONPATH目录(如果进行了设置) 3、标准链接库目录 4、任何.pth文件的内容(如果存在的话) 这四个组件合起来就成了sys.path。第一个和第三个是自动定义的。第二个与第四个就可以用于拓展路径,下面介绍4个目录使用方式。

1、主目录

程序的主目录是第一个搜索导入文件的路径。这一入口的含义与你如何运行代码相关。当你运行程序的时候,这个入口是包含程序的顶层脚本文件的目录。当在交互模式工作时,这个入口就是你当前工作的目录。 因为这个目录总是先被搜索,如果程序完全位于单一目录,所有导入都会自动工作,而不需要配置路径。另一方面,由于这个目录是先搜索的,其文件也将覆盖路径上的其他目录中具有同样名称的模块。如果你需要在自己的程序中使用库模块的话,小心不要以这种方式意外地隐藏库模块。

2、PYTHONPATH目录

Python会对此环境变量(如果你设置了的话)从左至右搜索导入的模块,PYTHONPATH是设置包含Python程序文件的目录的列表,这些目录可以是用户定义的,或平台特定的目录名。你可以把想导入的目录都加进来,而Python会使用你的设置来扩展模块搜索的路径。 因为Python先会搜索主目录,当跨目录的时候,这个设置才显得格外重要。也就是说,如果你需要被导入的文件与进行导入的文件处于不同目录时可以使用此环境变量来设定。

3、标准库目录

Python会自动搜索标准库模块安装在机器上的那些目录。因为这些一定会被搜索,通常是不需要添加到PYTHONPATH上的。

4、.pth文件目录(Python3.x)

Python有一个相当新的功能,允许用户把有效的目录添加到模块搜索路径中去,也就是文件名后缀为.pth的文件中。此文件可以放在: Windows中 - Python安装目录的顶层(例如C:\Python3.x\)或者在标准库所在位置的sitepackages子目录中(例如C:\Python3.x\Lib\sitepackages) 类Unix中 - 文件可能位于/usr/local/lib/python3.x/sitepackages或/usr/local/lib/sitepython中。 文件的格式是每一行一个目录,Python会把重复的目录和不存在的目录过滤掉。

五、配置搜索路径

我们可以手动设置的就是PYTHONPATH与.pth文件。PYTHONPATH设置方式,跟其他环境变量设置方式相同,每个路径之间使用分号隔开(;),.pth设置方式就是之前所说的那些目录里创建文件。 例如:在Windows,我们可以创建pydir.pth到C:\Python3.x\里。想要查看所有的搜索路径,我们可以使用sys.path来查看

>>> import sys
>>> sys.path
['', 'D:\\Program Files\\Anaconda\\python37.zip', 'D:\\Program Files\\Anaconda\\DLLs', 'D:\\Program Files\\Anaconda\\lib', 'D:\\Program Files\\Anaconda', 'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python37\\site-packages', 'D:\\Program Files\\Anaconda\\lib\\site-packages', 'D:\\Program Files\\Anaconda\\lib\\site-packages\\win32', 'D:\\Program Files\\Anaconda\\lib\\site-packages\\win32\\lib', 'D:\\Program Files\\Anaconda\\lib\\site-packages\\Pythonwin']

六、模块文件选择

我们导入模块的时候,不需要后缀名的。比如,导入mymodule.py时,只需要写import mymodule 就可以。import b的时候,可以导入的文件为: 1、b.py源代码文件 2、b.pyc字节码文件 3、导入文件名为b的文件夹 4、编译扩展模块(通常用C或C++来编写),导入时使用动态链接(例如类Unix系统的b.so以及Cygwin和Windows的b.dll或b.pyd) 5、用C编写好的内置模块,并通过静态连接至Python 6、ZIP文件组件,导入时会自动解压缩 7、内存内映像,对于frozen可执行文件 8、Java类,在Jython版本Python中使用 9、.NET文件,在IronPython的Python版本中使用


原文发布于微信公众号 - TeamsSix(OldCat0111)

原文发表时间:2019-02-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券