首页 > 技术文章 > Python 模块和包

nuoyanli 2019-10-17 14:03 原文

模块的基本使用

Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。

例子

下例是个简单的模块 test.py

def print_func( name):
   print"Hello : ", name)

模块的引入

import 语句

模块定义好后,我们可以使用 import 语句来引入模块,语法如下:

import module1, module2,... modulen

比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。在调用 math 模块中的函数时,必须这样引用:

模块名.函数名

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 test.py,需要把命令放在脚本的顶端:

# 导入模块
import test
 
# 现在可以调用模块里包含的函数了
test.print_func("nuoyanli")

以上实例输出结果:

Hello : nuoyanli

一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。

from…import 语句

Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:

from modname import name1, name2, ... namen

例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:

from fib import fibonacci

这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci
单个引入到执行这个声明的模块的全局符号表。

from…import* 语句

把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
例如我们想一次性引入 math 模块中所有的东西,语句如下:

from math import *

搜索路径

当你导入一个模块,Python 解析器对模块位置的搜索顺序是:

1、当前目录
2、如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
3、如果都找不到,Python会察看默认路径。Linux下,默认路径一般为/usr/local/lib/python/。

模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录

PYTHONPATH 变量

作为环境变量,PYTHONPATH 由装在一个列表里的许多目录组成。PYTHONPATH 的语法和 shell 变量 PATH 的一样。
在 Windows 系统,典型的 PYTHONPATH 如下:

set PYTHONPATH=c:\python3.7\lib

在 Linux系统,典型的 PYTHONPATH 如下:

set PYTHONPATH=/usr/local/lib/python

在这里插入图片描述
导入模块的搜索路径有哪些?它们的优先级是?
内存 > 内置 > sys.path的路径顺序遍历 自定义模块(自己写的,系统写的第三方,别人写的第三方)

Python中的包

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。

简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。

考虑一个在 package_nuoyanli 目录下的 nuoyanli1.py、nuoyanli2.py、__init__.py 文件,test.py 为测试调用包的代码,目录结构如下:

test.py
package_nuoyanli
|-- __init__.py
|-- nuoyanli1.py
|-- nuoyanli2.py

源代码如下:

package_nuoyanli/nuoyanli1.py

def nuoyanli1():
   print "I'm in nuoyanli1"

package_nuoyanli/nuoyanli2.py

def nuoyanli2():
   print "I'm in nuoyanli2"

现在,在 package_nuoyanli 目录下创建 __init__.py
package_nuoyanli/__init__.py

if __name__ == '__main__':
    print(作为主程序运行')
else:
    print(package_nuoyanli 初始化)

然后我们在 package_nuoyanli 同级目录下创建 test.py 来调用 package_nuoyanli

test.py

# 导入包
from package_nuoyanli.nuoyanli1 import nuoyanli1
from package_nuoyanli.nuoyanli2 import nuoyanli2
 
nuoyanli1()
nuoyanli2()

以上实例输出结果:

package_nuoyanli 初始化
I'm in nuoyanli1
I'm in nuoyanli2

如上,为了举例,我们只在每个文件里放置了一个函数,但其实你可以放置许多函数。你也可以在这些文件里定义Python的类,然后为这些类建一个包。

模块的制作及其发布

创建一个这样的目录结构:
在这里插入图片描述
setup.py文件:

from distutils.core import setup
setup(
    name="this_fm",# 模块的名字
    version="1.0", # 模块版本
    description="this_fm belongs to this_m", # 模块描述
    author="nuoyanli", # 模块制作者
    py_modules=['suba.a','suba.b','subb.a','subb.b'] # 模块包含哪些文件
)

创建模块

1.使用命令行(cmd)进入包所在路径
执行标准化构建:

python setup.py build

在这里插入图片描述
构建后得到结构如下:
在这里插入图片描述
2.执行打包命令
生成发布压缩包

python setup.py sdist

在这里插入图片描述
打包后,生成最终发布的压缩包this_fm-1.0.tar.gz
在这里插入图片描述

发布之后的目录结构包含的信息:

1.MANIFEST:这个文件包含发布中的文件列表
2.dist/this_fm-1.0.tar.gz:发布包
3.setup.py:用来存放元数据

到这里模块发布成功!
当然也可以从你打包的或者其他第三方模块安装:
首先找到模块解压包,解压:
在这里插入图片描述
解压之后执行命令:

python setup.py install

在这里插入图片描述
在使用install安装命令,还可以选择模块安装目录:

python setup.py install --prefix=安装路径

over!

推荐阅读