您的位置:首页 > 编程语言 > Python开发

python自定义包使用

2015-06-25 09:39 429 查看
1. 介绍
python每个py可以看成一个模块。常见的情况是,如果写好一个.py文
件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的.py文件所在的目录,然后import即可。

如果将相关的py文件放到一个目录下然后在加上一个__init__.py文件,就构成了一个包。在每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。当你将一个包作为模块导入(比如从 xml 导入 dom )的时候,实际上导入了它的 __init__.py 文件。一个包是一个带有特殊文件 __init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。

python在执行import语句时,它执行了如下操作:

1、创建一个新的,空的module对象(它可能包含多个module);

2、把这个module对象插入sys.module中

3、装载module的代码(如果需要,首先必须编译)

4、执行新的module中对应的代码。

在执行第3步时,首先要找到module程序所在的位置,其原理为:
1)当前目录
2)环境变量中PYTHONPATH中指定的路径列表中依次搜索
3)python的安装设置相关的默认路径,在Unix下,通常为/user/local/lib/python
正因为存在这样的顺序,如果当前 路径或PYTHONPATH中存在与标准module同样的module,则会覆盖标准module。也就是说,如果当前目录下存在xml.py,那么执
行import xml时,导入的是当前目录下的module,而不是系统标准的xml。

2. 简单目录结构下模块调用方法
如test中调用fun中的sum函数,目录机构如下:
1) 在同一目录下。直接引用名字即可
--maindir
fun.py
test.py
调用方法:import fun
fun.sum()
2)不同目录
--maindir
--subdir
fun.py
sum.py
调用方法1: 1)在subdir中创建文件__init__.py(将subdir看成一个包对待)
2) 在test.py中
import subdir.fun
subdir.fun.sum()
调用方法2:将subdir目录添加到搜索路径,在test中:
#加载到fun所在的目录
import sys
sys.path.append('subdir')##也可通过添加环境变量的方法,如export PYTHONPAHT=$PYTHONPATH:/**/maindir/subdir
###此后使用等同于同一目录
import fun

fun.sum()
从上例可看出,如果添加fun.py的路径到模块调用的搜索路径下,那就等同于与其在同一目录下的使用。如上2中的调用方法2。如果搜索路径是fun.py所在的目录,可将其目录添加__init__.py)的方式,看成一个包,通过import 目录名.fun 的加载方式使用其中函数,如上2中的调用方法1

3. 复杂目录架构下模块调用方法

采用sys.path.append加载到文件所在目录的方式,对于少数文件还可,如果目录层次复杂、数目较多时,就会变得吃力。此时就要通过环境变量PYTHONPATH和__init__.py同步使用的方式。如下多级目录:

--maindir
--dir1
--subdir1
fun.py
--dir2
--subdir2
test.py
调用方法:
1) 将maindir作为一个主目录,增加到环境变量中,如miandir所在目录为/system_enc/python/maindir,可将subdir1
目录添加到环境变量中:
export PYTHONPAHT=$PYTHONPATH:/system_enc/python/maindir
此后,加载模块时,可以此开始。
2)在需要被调用的模块的所在层级目录中均增加__init__.py文件,到上述所添加的环境变量中的主目录为止。此后编译会将其层目录看做一个包进行处理,查找其下的文件模块。
如上,test.py调用fun.py,就需要在fun.py所在的目录subdir1及上级目录dir1都增加__init__.py文件,到主目录maindir为止。

--maindir
--dir1
__init__.py
--subdir1
__init__.py
fun.py
--dir2
--subdir2
test.py

注:上述中1)和2)缺一不可。__init__.py,被动的模块中需要增加,主调函数所在目录中不需要添加。

4. __init__.py文件内容
一个包是一个带有特殊文件
__init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。 __init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容,下文详细介绍。

1. 定义一个函数
在__init__.py中定义一个函数,可直接通过目录名.函数名来调用。
如上3中,在dir1总定义一个demo函数,在test.py中,可通过import dir1
dir1.demo()来进行调用

--maindir
--dir1
__init__.py ###def demo():
--subdir1
__init__.py
fun.py
--dir2
--subdir2
test.py
2. 导入其他包或模块
当我们导入这个包的时候,__init__.py文件自动运行,在其中可以添加导入模块的命令,这样我们就不需要将所有的import语句写在一个文件里了,也可以减少代码量。

不需要一个个去导入module了。

__init__.py 中还有一个重要的变量,叫做 __all__。我们有时会使出一招“全部导入”,也就是这样:from PackageName import *

这时 import 就会把注册在包 __init__.py 文件中 __all__ 列表中的子模块和子包导入到当前作用域中来。比如:

--maindir
--dir1
__init__.py ###__all__ =["test1", "subdir1"]
test1.py
--subdir1
__init__.py ###__all__ =["fun"]或import fun
fun.py
--dir2
--subdir2
test2.py
此时在test1.py中
form subdir1 import * ###加载了dir1下fun模块
fun.sum()#####不需要加subdir1层次
在test2.py中
form dir1 import * ## ###加载了dir1下的test1和subdir1模块,以后调用不需要加dir1
test1.sum()####调用时已dir1下目录为起始,不需要加dir1层次
subdir1.fun.sum()####调用时已dir1下目录为起始,不需要加dir1层次

注:以*导入时,package内的module是受__init__.py限制的,如无则后无法使用此模块。

5. 参考资料:
http://www.cnpythoner.com/post/2.html
/article/9195972.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: