防伪码:忘情公子著
python中的模块
将代码量较大的程序分割成多个有组织的、彼此独立但又能互相交互的代码片段,这些自我包含的有组织的代码段就是模块。
模块在物理形式上表现为以.py结尾的代码文件:
一个文件被看作一个独立的模块,一个模块也可以被看作是一个文件
模块的文件名就是模块的名字加上扩展名.py
每个模块都有自己的名称空间
python允许"导入"其它模块以实现代码重用,从而也实现了将独立的代码文件组织成更大的程序系统:
在python中,模块也是对象
在一个模块的顶层定义的所有变量都在被导入时成为了被导入模块的属性
python程序架构:
一个python程序通常包括一个顶层程序文件和其它的模块文件(0个、1个或多个)
顶层文件:包含了程序的主要控制流程
模块文件:为顶层文件或其它模块提供各种功能性组件
模块首次导入(或重载)时,python会立即执行模块文件的顶层程序代码(不在函数内的代码)
而位于函数主体内的代码直到函数被调用后才会执行
可以使用help('modules')来查看系统中有哪些python的标准库模块。
模块的执行环境:
模块是被导入的,但模块也可以导入和使用其它模块,这些模块可以用python或其它编程语言写成
模块可内含变量、函数以及类来进行其工作,而函数和类可以包含变量和其它元素
模块分类:
a.标准库(又称内置模块)
b.开源模块(又称第三方模块)
c.自定义模块
导入模块:
在导入模块时只能使用模块名,而不能使用带.py后缀的模块文件名
import语句:导入指定的整个模块,包括生成一个以模块名命名的名称空间
import module1 [, module2 [, ... moduleN]]
建议一个import语句只导入一个模块
import module as module_alias
一旦使用了别名,则仅能使用别名进行调用
from-import语句:常用于只导入指定模块的部分属性至当前名称空间
from module import name1 [, name2 [, ... nameN]]
动态导入模块:
当我们知道模块的名称和路径,但是是以字符串的形式存在的,此时无法通过import语句直接导入
这时我们就能以动态导入模块的方式导入该模块
import importlib
modname = 'lib.fib'
__import__(modname)
还可以使用以下官方推荐的方式动态导入模块,与上面的__import__(modname)效果一致:
importlib.import_module(modname)
import和from-import是赋值语句:
import和from是可执行语句,类似于def,因此,它们可以嵌套在if测试中,出现于def中等等
python执行到这些语句时才会对其进行解析,这意味着,所有来自模块的属性仅在import语句执行后才能使用
import和from都是隐性赋值语句:
import将整个模块对象赋值给一个变量名
from将一个或多个变量名赋值给导入此模块的模块中的同名对象
模块就是名称空间:
模块的名称空间可以通过属性__dict__或dir(M)获取
模块属性可以通过点号(.)运算符获取,格式为M.attr
模块是一个独立的作用域(本地变量就是全局变量)
import的工作机制:
import语句导入指定的模块时会执行三个步骤:
找到模块文件
在指定的路径下搜索模块文件
编译成字节码
文件导入时就会编译,因此,顶层文件的.pyc字节码文件在内部使用后会被丢弃
只有被导入的文件才会留下.pyc文件
执行模块的代码来创建其所定义的对象
模块文件中的所有语句会依次执行,从头至尾
而此步骤中任何对变量名的赋值运算,都会产生所得到的模块文件的属性
注意:模块只在第一次导入时才会执行如上步骤:
后续的导入操作只不过是提取内存中已加载的模块对象
reload()可用于重新加载模块
模块的顶层执行及被导入:
一个模块文件可以同时支持顶层执行(作为顶层文件)或被导入(作为模块文件)。
每个模块都有个名为__name__的内置属性,python会自动设置该属性:
如果文件是以顶层程序文件执行,在启动时,__name__的值为"__main__"
如果是被导入,则__name__的值为模块名
可以在模块文件中检测自己的__name__属性,以之实现在执行时运行指定的代码,常用于模块的自我测试。
#!/usr/bin/python
def testFunc():
print "Hello world"
if __name__ == "__main__":
testFunc()
模块搜索:
python解释器在import模块时必须先找到对应的模块文件,python将在以下这些目录中查找模块文件:
程序的主目录;
PYTHONPATH目录(如果设置了此变量);
标准链接库目录;
任何.pth文件的内容(如果存在.pth文件)
这四个组件组合起来即为sys.path所包含的路径,而python会选择在搜索路径中的第一个符合导入文件名的文件
python中的包
如果我们开发了一系列的模块给别人使用,而这些模块是有关联性的,如果照前面说的,要设置模块搜索路径,然后将这一系列的模块放进去,这样就会很麻烦,于是就有了包的概念。
包用于将一组模块归并到一个目录中,此目录即为包,目录名即为包名。
包是一个有层次的文件目录结构,它定义了一个由模块和子包组成的python应用程序执行环境
基于包,python在执行模块导入时可以指定模块的导入路径,如:
import dir1.dir2.mod1
要使用如图所示的package1,则py_pkg_mod容器必须要在模块搜索路径中。使用以下命令导入:
import package1.mod1
包导入语句的路径内的每个目录内都必须有__init__.py文件:
__init__.py可包含python代码,但通常为空;
仅用于扮演包初始化的挂钩、替目录产生模块命名空间以及使用目录导入时实现from *行为的角色
发布python模块或程序:
python模块、扩展和应用程序可以按以下几种形式进行打包和发布:
压缩文件(使用distutils模块):
windows的zip文件和类Unix平台的.tar.gz文件
自动解包或自动安装可执行文件:
windows中的.exe文件
自包含的,不要求安装的预备运行可执行程序:
windows的.exe文件、Unix上带有一个小的脚本前缀的ZIP压缩文件、Mac上的.app文件等
平台相关的安装程序:
windows上的.msi文件、Linux上常见的.rpm、src.rpm和.deb文件等;
python eggs:
较流行的第三方扩展
使用distutils发布模块:
distutils模块能够帮助完成模块或程序发布。
"发布"是指一个文件集合,这些文件联合在一起可使用distutils构建、打包和发布模块
创建好的发布可以用于安装,也可上传到PyPI与他人共享
创建发布的步骤:
1、将各代码文件组织到模块容器中;
2、准备一个README或README.txt文件;
3、而后在容器中创建setup.py文件,格式如下:
from distutils.core import setup
setup(
name = 'testmod', #包名
version = '0.0.1',
author = 'Forgotten',
author_email = 'chengyujia@126.com',
py_modules = ['testmod'], #此包内所有的模块列表,多个模块名之间用逗号隔开
url = 'http://itchentao.blog.51cto.com', #模块可以从哪里获取到,此处只是个样例
description = 'A simple module', #模块的简要描述
)
setup.py的常用参数:
name:包的名称(必需)
Version:版本号(必需)
author:作者名称
author_email:作者的电子邮件地址
maintainer:维护者的名称
maintainer_email:维护者的电子邮件地址
url:包的主页
description:包的简短描述
long_description:包的详细描述
download_url:包的下载位置
Classifiers:字符串分类器列表
py_modules:由所有模块名称组成的列表(必需)
此些模块可能位于包的根目录下(modulename),也可能位于某子包目录中(subpkg1.modulename)
packages:各子包名称组成的列表
platforms:适用的平台列表
license:许可证
setup.py的参数大体分为两类:
元数据信息(name、version等)
包中的内容列表(py_modules、packages等)
4、完成打包:
在要发布的容器目录中执行"python setup.py sdist"命令进行源码打包:
sdist可以指定以下格式进行打包:--formats=
zip:zip压缩文件
gztar:tar.gz压缩文件
bztar:tar.bz2压缩文件
ztar:tar.Z压缩文件
tar:tar文件
还可以在要发布的容器目录中执行"python setup.py bdist"命令进行二进制发行版打包:
bdist可以指定以下格式进行打包:--formats=
gztar:tar.gz压缩文件
ztar:tar.Z文件
tar:tar文件
zip:zip压缩文件
rpm:RPM包文件
pkgtool:Solaris pkgtool
wininst:windows上能自解压的zip格式的包
msi:Microsoft Installer
bdist_dump:做成tar、ztar、gztar、zip格式的包
bdist_rpm:做成rpm格式的包
bdist_wininst:做成wininst格式的包
bdist_msi:做成msi格式的包
获取帮助的方式:
python setup.py --help
python setup.py --help-commands:所有可以使用的命令,如build,install
python setup.py COMMAND --help:获取特定命令的帮助
python setup.py COMMAND --help-formats:获取特定命令支持使用的格式
5、安装打包好的模块:
使用python setup.py install命令安装源码打包文件
上传到PyPI上的包,可以使用pip,easy_install命令来安装
python中安装第三方模块包:
使用python setup.py install命令安装模块:有两个阶段(build、install)
如果不执行python setup.py build而直接执行python setup.py install,在安装时会自动进行build操作。
在执行python setup.py build时python会在执行这条命令的目录下创建一个build目录。
python setup.py build:
--build-base=/path/to/build_dir 指定目录进行build,build的过程将保存至指定目录下。
build完成后将会在build目录下生成以下目录,用以保存即将安装的模块文件:
lib:保存纯python语言所研发的模块
lib.platform:存放与平台密切相关的、无法实现跨平台的、编译好的库文件
python setup.py install:
install的过程仅仅只是将编译好的文件复制到指定的模块安装目录中。
在未指定安装目录时,默认将安装到第三方模块安装目录中(/python安装目录/lib/site-packages)
自定义安装路径:
--user=:安装至指定用户家目录中特定的目录下
常用于普通用户,因为普通用户对某些目录是没有写权限的
--prefix=:指定python库的安装路径
要对指定目录有写权限
--exec-prefix=:用于指定与python无关的、由其他语言实现的、跟平台相关的特定文件的安装路径
要对指定目录有写权限
深度定制:
--install-purelib=/path/to/python_lib
--install-platlib=/path/to/plat_lib
--install-lib=/path/to/lib
--install-purelib和--install-platlib选项可以用--install-lib来替代
若三个选项都指定了,则--install-lib的优先级最高
--install-scripts=/path/to/bin 指定可执行文件的安装路径
--install-data:指定数据文件的安装路径
--install-headers:指定用C写出来的可执行程序的头文件安装路径