python自定义包使用

来源:互联网 发布:象棋高手学软件 编辑:程序博客网 时间:2024/06/06 02:13
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
http://blog.csdn.net/fyh2003/article/details/6837624

0 0