Python环境安装之目录作用与模块查找

笔记要点

  • python安装后各个目录是干啥的,哪些是启动python解释器必须的?
  • python标准库有些模块是用C编写的,有些是用python写的,同时有些模块是直接内置在python解释器中,分别是哪些呢?
  • python是如何查找模块的呢? 在当前启动python的目录,python安装目录下的某几个目录和.zip文件,第三方模块所在目录site-package,最后是我们自己添加到sys.path的目录。

环境安装

我的环境:win7 + python3.7.7
window是下python环境的安装比较简单,一般情况下一路next就行。

更多安装的详细说明可以查看 python官方安装教程
python官方下载地址

环境安装成功测试

Windows

打开‘开始’菜单,输入‘cmd’后回车打开命令行控制台窗口,输入“python”或“py”回车确认,看看是否能进入python交互式界面,可以则安装成功。

安装目录介绍

我是直接默认安装的,当然,安装界面那里我是勾选了将Python添加到环境变量Path中的。
安装的主目录如下:C:\Users\Administrator\AppData\Local\Programs\Python\Python37
安装成功后目录内容如截图所示:
Python环境安装之目录作用与模块查找_第1张图片
Windows环境下的Python默认安装基本上把能装的都装了,它不仅包含python解释器运行所需,还带有整个Python标准库,TK界面库,IDEL开发工具,PIP模块安装工具,python帮助文档,等等。


目录介绍
DLLs: 这个目录里面有用C语言编写的Python模块(应该就是那些pyd后缀的文件,文件名大部分以下划线_开头),还有一些dll后缀的动态链接库文件,如sqlite3.dll,一些.cat后缀的文件(不知道是啥)。
这里面的一个模块unicodedata.pyd,这个模块官方文档是这样介绍的:此模块提供对 Unicode 字符数据库(UCD)的访问,该数据库定义所有 Unicode 字符的字符属性。这个是跟Unicode相关的,但是这句print(“我”)代码,就算没有这个模块也可以运行,但是我将 ‘我’ 用作变量名,没有这个模块则报错了,没搞明白为啥。

Doc: 帮助文档目录。

include:这里面的都是一些C语言的头文件,查了下这个官方解释器的源码项目CPython,发现里面源码那里所用的头文件跟这里很类似。不清楚这个目录的作用,删除这个目录不会影响python解释器的运行。

20200703 笔记补充 在设置标签《Python源码剖析》中讲到源码中的include目录包含Python提供的所有头文件,并说用户自己用C或C++编写自定义模块是,需要用到include目录的头文件,那么在Python发行版安装后的include目录应该就是出于同样的目的,即提供用户在使用C或C++扩展Python功能时所需使用的头文件。

Lib存放模块的地方。Python标准库中用python写的模块就在这里,而我们安装的第三方库是在Lib里面的一个site-package目录里面。

20200703 笔记补充 关于libs目录中说到的.lib.a库文件,这次了解了一些库文件的知识,下面单独列了一个小节笔记。关于这个libs目录的.lib库文件应该是windows环境中的导入库,.a库文件则应该是Linux环境的静态库文件(关于libs目录内库文件的说明这点还需要验证,暂时还未验证,目前先这样理解)

libs: 一些.lib后缀的静态库文件。没搞明白,没有也不影响python解释器运行。

Scripts: 这里面的是一些工具,.exe格式的文件,像easy_install.exe,pip.exe

tcl: 这里面是跟TK GUI相关的,看上去有几个版本和一些示例,不知道是否开发TK桌面程序必须的(因为在Dlls目录里面也有tk的动态链接库文件),后面有尝试tk桌面应用在测试看看。

tools: 用python写的工具。

漫无目的的尝试(最小必须)

**目标**:测试安装目录下那些文件哪些是维持Python解释器运行必须的
测试方法:逐个删除那些文件,测试哪些会影响Python交互式窗口的正常启动。
**结果**:如下图,只有**Lib目录下的部分模块(例如encodings包里面的,io模块),python37.dll **是必须的。(python.exe 跟 pythonw.exe 的差别是一个是有界面的,一个是无界面的)
这个测试没啥目的,做多点了解,这个算是维持python运行的最小所需吧,但是没有了大部分标准库,其实我们很多事都做不了,当然那些内置都可以使用,基本的类型,算术运算这些都是可以的。Python环境安装之目录作用与模块查找_第2张图片Python环境安装之目录作用与模块查找_第3张图片

测试最小环境时缺少部分文件时的错误

缺少部分模块时,错误如下
Fatal Python error,unable to load the file system codec , ModuleNotFoundError: No module named ‘encodings’ , 文件系统编码有关的错误。这个包里面的都是文件系统编码相关的模块。
Python环境安装之目录作用与模块查找_第4张图片
补充:python官方安装教程那里也介绍了官方提供的一个用于嵌入其他应用的最小python环境,那个环境就有标准库,但是删除GUI,IDLE,文档这些,且标准库是编译的,不是源码,这样整个文件才更小。


标准库

Windows环境下的python安装通常都带有整个python标准库。

了解一下概念

模块

python代码源文件是以.py作为后缀名的,通常一个.py文件就是一个模块。

关于库的话,库应该是一个逻辑分类,出于方便代码的组织管理,是各种封装好的功能模块的集合的一个称呼。像python自带的这些模块,我们称为标准库,一些第三方开源的像OpenCV库,还有科学计算的一些库,一般它们都包含了不止1个模块。


Python标准库

Python 标准库非常庞大,所提供的组件涉及范围十分广泛,正如以下内容目录所显示的。这个库包含了多个内置模块 (以 C 编写),Python 程序员必须依靠它们来实现系统级功能,例如文件 I/O,此外还有大量以 Python 编写的模块,提供了日常编程中许多问题的标准解决方案。其中有些模块经过专门设计,通过将特定平台功能抽象化为平台中立的 API 来鼓励和加强 Python 程序的可移植性。

Windows 版本的 Python 安装程序通常包含整个标准库,往往还包含许多额外组件。对于类 Unix 操作系统,Python 通常会分成一系列的软件包,因此可能需要使用操作系统所提供的包管理工具来获取部分或全部可选组件。

这个库主要是由一系列的模块组成。这些模块集可以不同方式分类。**有些模块是用 C 编写并内置于 Python 解释器中;另一些模块则是用 Python 编写并以源码形式导入。**有些模块提供专用于 Python 的接口,例如打印栈追踪信息;有些模块提供专用于特定操作系统的接口,例如操作特定的硬件;另一些模块则提供针对特定应用领域的接口,例如万维网。有些模块在所有更新和移植版本的 Python 中可用;另一些模块仅在底层系统支持或要求时可用;还有些模块则仅当编译和安装 Python 时选择了特定配置选项时才可用。

Python附带了一个标准模块库,在单独的文档Python库参考(以下称为“库参考”)中进行了描述。**一些模块内置于解释器中;它们提供对不属于语言核心但仍然内置的操作的访问,以提高效率或提供对系统调用等操作系统原语的访问。**这些模块的集合是一个配置选项,它也取决于底层平台。例如,winreg 模块只在Windows操作系统上提供。一个特别值得注意的模块 sys,它被内嵌到每一个Python解释器中。变量 sys.ps1 和 sys.ps2 定义用作主要和辅助提示的字符串 。
内容来自《Python标准库》
python官方教程第6节模块

总结

  1. Python标准库的模块有用C编写的。目前就知道安装目录下的DLLs目录内的模块是用C编写的。具体到有哪些模块是C语言写的,是干啥的,等后面用到时有详细了解在慢慢补充。
  2. Python标准库的模块有用Python编写的。在Lib目录中。
  3. 部分用C语言编写的模块是直接内置于Python解释器中。哪些模块是内置于Python解释器中呢? 首先不需要import的都是内置的(内置类型,内置函数,内置常量),另外sys模块也是内置在python解释器的,还有没有呢?

Python模块查找

默认情形下的模块搜索路径

就像吩咐人做事一样,要先找到人才可以让他做事。Python解析器要执行代码,同样要先找到代码才行。Python解析器在执行代码的时候是从哪里找呢?

  1. 先从python解释器的内置模块中搜索
  2. 在sys.path指定的路径中搜索(sys.path的值从哪来?看下面)

以下内容大部分引用自Python官方文档。

当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的**内置模块**。如果没有找到,然后解释器从sys.path变量给出的目录列表里寻找名为 spam.py 的文件。sys.path初始有这些目录地址:

1.在开始时,添加一个空条目,该条目对应于当前目录。

2.如果环境变量PYTHONPATH存在,如环境变量中所述,则接下来添加其条目。请注意,在Windows上,此变量中的路径必须用分号分隔,以区别于驱动器标识符中使用的冒号( C:\ 等)。

3.附加的 “application paths” 可以同时添加到注册表HKEY_CURRENT_USER 和 HKEY_LOCAL_MACHINE 分支下的:samp:\SOFTWARE\Python\PythonCore{version}\PythonPath 中作为子键。以分号分隔的路径字符串作为默认值的子键将导致每个路径添加到sys.path。(请注意,所有已知的安装程序都只使用HKLM,因此HKCU通常为空。)

4.如果设置了环境变量PYTHONHOME,则将其假定为 “Python 主目录” 。否则,主Python可执行文件的路径用于定位 “landmark 文件” ( Lib\os.py 或 pythonXY.zip )以推断 ”Python 主目录“ 。如果找到了Python主目录,则基于该文件夹将相关的子目录添加到sys.path(Lib , plat-win 等)。否则,核心Python路径是从存储在注册表中的PythonPath构造的。

5.如果找不到Python Home,也没有指定PYTHONPATH环境变量,并且找不到注册表项,则使用具有相对条目的默认路径(例如 .\Lib; .\plat-win 等等)

另外:默认情况下,python解释器在初始化启动时会自动导入site模块,这个模块也会添加一些特定的路径到sys.path中,这个site模块是用python源码实现的,查看源码内的注释:“Append module search paths for third-party packages to sys.path",应该是说添加第三方模块搜索路径到sys.path中,主要就是添加site-package这个目录****(包括全局的site-package和用户级别的site-package)****。
这个模块将在初始化时被自动导入。 此自动导入可以通过使用解释器的 -S 选项来屏蔽。导入此模块将会附加域特定的路径到模块搜索路径并且添加一些内建对象,除非使用了 -S 选项。在此例中,模块可以被安全地导入,而不会对模块搜索路径和内建对象有自动的修改或添加。要明确地触发通常域特定的添加,调用函数 site.main()。
**
在初始化后,Python程序可以更改 sys.path。包含正在运行脚本的文件目录被放在搜索路径的开头处, 在标准库路径之前。这意味着将加载此目录里的脚本,而不是标准库中的同名模块。 除非有意更换,否则这是错误。更多信息请参阅 标准模块。

参考资料:
python官方安装教程之查找模块
python官方教程之模块
python标准库之site模块


默认情形下sys.path取值的验证

根据上面官方关于sys.path取值情形的描述:
1,空格,表示当前目录。
2,我没有设置PYTHONPATH环境变量,这一点我没有。
3,安装python应用环境时的注册表信息,这个我查了下,我有HKCU,没有找到HKLM。(我想这是因为我是选择默认安装到当前用户路径的原因),这个的注册表项有两个值,分别指向DLLs和Lib目录。
Python环境安装之目录作用与模块查找_第5张图片
4,这里的描述看不大明白,但是结合结果看,主要是围绕python安装的主目录,添加python安装主目录下的几个路径到sys.path中。pythonXX.zip文件路径,Lib目录等,感觉有部分路径跟第3点重复了。
5,跟第四类似,同样是用于添加Python模块所在的路径信息,但是第5点生效的前提是前面的2,3,4点全都不生效,并且模块路径都变成了相对路径(为啥是相对路径,我想应该是前面的2,3,4点都是围绕Python的绝对路径来的,既然2,3,4点都不生效了,说明找不到Python安装主目录的绝对路径,所以只能采用相对路径了)。这里我的不属于这种情形。
所以,我只有1,3,4点,3,4感觉有部分路径重复了
另外,就是site模块所注入的site-package目录信息。

验证:

我启动python环境,打印了下这个sys.path的值,我的python安装目录是:C:\Users\Administrator\AppData\Local\Programs\Python\Python37。打开cmd命令,目前是在C:\Users\Administrator目录下,在这个目录下我还有个testsite.py 模块文件,里面只有一句print()代码。
现在启动python交互式命令环境:
Python环境安装之目录作用与模块查找_第6张图片
我在site模块的源码里面添加了一些打印代码,从上图中可看到开始加载site模块的开头打印的路径信息,和加载完site模块的打印路径信息看,第三方模块所在的site-package目录是site模块添加的。其他的几个路径信息符合3,4点所描述的。
['',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages']
重点这个sys.path里面的路径信息是采用list存放的,所以是有序的,在进行模块搜索的时候,就是按照这个list里面的顺序进行搜索的,所以最先搜索的是我们应用的当前目录,如果找到模块就不会继续找,这样的话就有可能存在一个问题:就是如果我们自己的模块与官方的模块出现同名的话,所有代码最后都是调用了我们的模块,而标准库的模块则永远不会被调用到,所以,切记,不要与标准库模块同名,除非你确定是要覆盖掉官方的实现。

修改sys.path

  1. 我们可以在代码里面直接添加我们要搜索的路径信息到sys.path中。
  2. python官方所说的通过自定义一个._pth 文件的方式,完全覆盖默认的sys.path。
  3. python 命令行有几个选项:-E -s -S -I ,这些可以分别禁用某些路径被写入到sys.path。如-E ,忽略所有 PYTHON* 环境变量,例如可能已设置的 PYTHONPATH 和 PYTHONHOME。

要点1:有时候,我们自己写的代码出现找不到模块时,很可能就是因为我们写的模块所在的路径不在sys.path中,导致解释器搜索不到。这时可以打印下sys.path看看是否这样。
要点2:python给我们提供了自定义进行覆盖默认sys.path的方式,通过自定义sys.path的方式,我们可以限制python程序加载运行时所能搜索的路径,可以隔离不同应用让它们有不同搜索路径,自定义的方式很适合在我们将python嵌入到我们自己的应用程序的时候,这样做我们应用内的python不会跟用户系统本身已存在的python环境冲突,导致出现问题。具体的可以查看上面给出的官方的文档中查找模块相关的内容。

Python安装目录下的libs目录中的库文件

这个libs目录里面的“库文件”跟上面说到Python标准库库文件是同样的概念。都是函数功能模块的集合。
不同的是上面讲到的Python语言的库。
这个libs目录里面的库文件应该是属于c或者c++函数库。它们应该是Python解析器所用到的函数库(这里要知道Python解释器的官方实现是Cpython,是采用C语言编写),那么这个.lib库文件是到底是静态链接库还是导入库呢?(如何验证呢?暂时不清楚),应该是导入库(导入库不包含函数实现真正的二进制内容,真正的函数实现是在dll文件中)。
在python源码中,pythoncore(即python解释器的核心部分)打包生成pythonXX.dll文件和pythonXX.lib文件。pyhtonXX.lib文件应该是对PythonXX.dll文件内所包含的函数的说明,程序一般是通过导入库来使用dll文件内的函数的。
为啥安装后的目录内有这个目录,可能也是用于自定义编写c或c++模块时使用。

Windows环境中.lib文件

.lib库文件可以分为:静态链接库和导入库(动态链接库)
静态链接库:存储着目标文件实体(即各个函数的二进制实现表示)
导入库:没有存储目标文件实体,仅仅存储着两个信息:一个是函数所在的DLL文件,二是DLL文件所在的文件夹信息。
.dll后缀文件是Windows环境中的动态链接库,动态链接库应该是通过导入库来访问的。

《Python源码剖析》 《程序是怎样跑起来的》第8章


来我的小店逛逛吧休闲内衣家居服
Python环境安装之目录作用与模块查找_第7张图片

你可能感兴趣的:(Python基础)