龙空技术网

python基础篇:模块的高级技巧

平地摔VS天然呆 272

前言:

眼前咱们对“python模块搜索”大约比较关怀,大家都想要学习一些“python模块搜索”的相关文章。那么小编也在网络上网罗了一些有关“python模块搜索””的相关资讯,希望我们能喜欢,咱们快快来学习一下吧!

上一节,我们讲解了Python模块的基础知识,这一节我们继续深入了解模块的更多知识,从而让大家全面了解、掌握和运用模块到我们实际的编程中。

在上一节中有一句话“接着我们在这个文件所在目录运行Python解释器IPython”,不知道大家还记不记得。这就话背后隐含的意思是,在这个文件(模块)目录下,我们才可以import到这个模块,否则会报错,说找不到这个模块。这里,就涉及到了Python模块的搜索路径。

Python模块的搜索路径

当一个名为mylib的模块被导入时,解释器首先搜索内置模块是不是有该名字的模块。

如果没有找到,接着搜索sys.path列出的目录下面是不是有名为mylib的模块。

sys.path的初始化按以下几个路径的顺序:

(1)包含输入脚本的目录,如果没有输入脚本则是当前目录;

(2)环境变量PYTHONPATH(一个目录名称的列表);

(3)Python库的安装目录。

下面我们来验证一下sys.path所包含的路径,编写一个Python文件initpath.py如下:

# Author: veelion# file: initpath.pyimport sysprint('\n'.join(sys.path))

命令行下运行:python3 initpath.py得到如下结果:

$ python mylib.py/home/veelion/p2/tutorial/md_Python/codes/home/veelion/.virtualenvs/py3.7/lib/python37.zip/home/veelion/.virtualenvs/py3.7/lib/python3.7/home/veelion/.virtualenvs/py3.7/lib/python3.7/lib-dynload/usr/lib/python3.7/home/veelion/.virtualenvs/py3.7/lib/python3.7/site-packages

我们可以发现,initpath.py所在的目录是sys.path列表的第一个元素。符合上面三条原则的顺序。

接下来我们通过交互式Python解释器来看看sys.path,运行CPython解释器再导入sys:

>>> import sys>>> sys.path['', '/home/veelion/.virtualenvs/py3.7/lib/python37.zip', '/home/veelion/.virtualenvs/py3.7/lib/python3.7', '/home/veelion/.virtualenvs/py3.7/lib/python3.7/lib-dynload', '/usr/lib/python3.7', '/home/veelion/.virtualenvs/py3.7/lib/python3.7/site-packages']

细心的小猿可以发现,sys.path的第一项是个空字符串,和运行脚本方式下的第一项——当前路径不一样。为什么会是空字符串呢?

这是因为,当交互式运行Python解释器时(或者脚本是从标注输入读取的),可以认为传给解释器的脚本文件路径为空,那么就把sys.path[0]设置为空字符串,它告诉Python搜索模块时先从当前文件夹开始。

以上两种方法验证的sys.path都符合预期,然而IPython有点例外。

In [1]: import sysIn [2]: sys.pathOut[2]: ['/home/veelion/.virtualenvs/py3.7/bin', '/home/veelion/.virtualenvs/py3.7/lib/python37.zip', '/home/veelion/.virtualenvs/py3.7/lib/python3.7', '/home/veelion/.virtualenvs/py3.7/lib/python3.7/lib-dynload', '/usr/lib/python3.7', '', '/home/veelion/.virtualenvs/py3.7/lib/python3.7/site-packages', '/home/veelion/.virtualenvs/py3.7/lib/python3.7/site-packages/IPython/extensions', '/home/veelion/.ipython']

IPython 并没有把当前路径放在第一项。这样就会导致你写的模块与系统模块重名时,它import的是系统模块而不是你写的模块,而前面两种方式就是导入你写的模块而非系统模块。这一点在使用IPython时要格外注意。

注意你可以在程序中修改sys.path。sys.path是一个Python的列表结构,我们可以像修改列表那样修改它,增加、删除、修改路径顺序。比如,可以通过sys.path.insert(0, 'my-module-path')来把我们自己写的模块的路径放到搜索路径的最前面,优先搜索自己的模块。

编译后的Python文件:*pyc

为了加速模块的加载时间,Python会缓存已经编译好的模块,并把它们放在与模块同级目录下的__pycache__文件夹下面,编译好的模块的命名方式为:module.version.pyc,其中的version包含Python的版本号。比如:

$ ls __pycache__/m1.cpython-36.pyc m2.cpython-36.pyc

cpython-36就是编译这个模块的Python信息:用CPython 3.6 进行编译的。这种命名方式方便不同版本的Python编译的模块同时存在而不造成冲突。

Python在两种情况下不检查缓存。

其一,它总是重新编译并且不存储直接从命令行加载的模块的结果。

其二,如果没有模块源码文件,它不会检查缓存。要支持非源(仅编译)分发,已编译的模块必须位于源码目录中,并且不得有模块源码。

举个例子理解一下这两点:

(1)如果在命令行下运行python m1.py,Python总是从新编译m1.py,但不会保存pyc文件,因为每次都有重新编译就没必要保存了。

(2)如果我们导入m1模块时,搜索路径目录下只有m1.pyc而没有m1.py文件,那就直接导入m1.pyc。这种方式适合把编译好的pyc发布给其他人而不是给它们源代码,使用这种方式时,把.pyc文件从__pycache__中拷贝到.py文件相同的目录下并删掉.py文件即可。

Python模块的高级技巧

(1)模块compileall可以把一个文件夹下所有的py文件编译成.pyc文件。

它的使用很简单,命令行运行的格式如下:

python -m compileall 文件夹或文件名

更多选项可以通过:python -m compileall -h查看。

(2)编译成.pyc文件时,可以给Python命令两个选项:-O和-OO,使得编译后的文件更小。

-O 去除assert语句;

-OO 去除assert语句和__doc__ string。

根据情况来使用这两个选项,用compileall编译文件时加这个选项就是这样子的:

python -O -m compileall 文件夹或文件名

生成的pyc文件名称里面有opt-标签,-O的标签是opt-,-OO的标签就是opt-2。比如:

$ ls -F -1 __pycache__/m1.cpython-36.opt-1.pycm1.cpython-36.opt-2.pycm1.cpython-36.pyc

(3).pyc和.py文件都不会使程序运行得更快(不会提高运行速度)。但是,.pyc文件能使加载速度更快,因为少了编译的过程。

Python标准模块

Python附带了一个标准模块库。其中一些模块内置在解释器中,它们提供对不属于语言核心但仍然内置的操作的访问,以提高效率或提供对系统调用等操作系统原语的访问。这些模块的集合是一个配置选项,它也取决于底层平台。例如,winreg模块仅在Windows系统上提供。一个值得注意的模块是sys,它内置于每个Python解释器中。

Python的标注模块会在我们今后的编程中不断遇到和使用,具体的学习可以在今后用到时再学习。你需要记住的一点是:当你写Python代码需要某些基本功能时,一定要先找找看是否已经有标准模块存在,是否已经有人写好了包含这些功能的模块,最后才要觉得自己要不要实现这些功能。

Python内置函数dir()

dir()用来查看模块里面定义的名字,包括:变量名,模块名,函数名等等。

它返回一个list:

In [5]: import my_first_moduleIn [6]: dir(my_first_module)Out[6]: ['MY_NAME', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'my_add', 'my_print']

如果调用dir()不传递参数,则列出当前已经定义的所有名字:

用dir()可以查看所有的内置类型、变量、函数等,方法是借助标准模块builtins:

Python模块高级技巧总结

(1)Python的搜索路径,顺序一定要搞得清;

(2)编译后的.pyc文件;

(3)dir()内置函数查看模块定义的名字。

做什么事情都需要不断地坚持下去,编程也一样。现在python语言十分火热,职场对python的需求也很高,薪资待遇都很棒。所以希望大家能够坚持学习,‘剩’者为王,坚持下来的人才有资格称王。如果你觉得本文对你的学习有帮助的话,不妨点个关注,我会持续更新。

标签: #python模块搜索