2017年12月29日星期五

6、Python模块

1.7.Python模块

简单地说,一个模块是由Python代码的文件。一个模块可以定义函数,类和变量。模块还可以包括可运行的代码。

1.7.1 模块的定义和导入

例:以下代码定义在support.py文件中
def print_func( par ):
   print "Hello : ", par
   return

在别的模块比如(hello.py)中可以导入定义好的模块
#!/usr/bin/python

#导入模块
import cn.itcast.test.support
# 使用导入的模块中的函数
cn.itcast.test.support.print_func("Zara")

#------------------------------------------------
#或者
from cn.itcast.test.support import print_func

print_func("Zara")




1.7.2 模块和包

python中一个文件可以被看成一个独立模块,而包对应着文件夹,模块把python代码分成一些有组织的代码段,通过导入的方式实现代码重用。

1.7.1 模块搜索路径

导入模块时,是按照sys.path变量的值搜索模块,sys.path的值是包含每一个独立路径的列表,包含当前目录、python安装目录、PYTHONPATH环境变量,搜索顺序按照路径在列表中的顺序(一般当前目录优先级最高)。
[/home/zhoujh/study_workspace/studynotes/python/python_base, /usr/local/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg, /usr/local/lib/python2.6/site-packages/redis-2.2.1-py2.6.egg, /usr/local/lib/python2.6/site-packages/Flask-0.8-py2.6.egg, /usr/local/lib/python2.6/site-packages/Jinja2-2.6-py2.6.egg, /usr/local/lib/python2.6/site-packages/Werkzeug-0.8.3-py2.6.egg, /usr/local/lib/python2.6/site-packages/tornado-2.2.1-py2.6.egg, /usr/local/lib/python2.6/site-packages/MySQL_python-1.2.3-py2.6-linux-x86_64.egg, /usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-x86_64.egg, /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg, /home/zhoujh/python_workspace/python_app, /usr/local/lib/python26.zip, /usr/local/lib/python2.6, /usr/local/lib/python2.6/plat-linux2, /usr/local/lib/python2.6/lib-tk, /usr/local/lib/python2.6/lib-old, /usr/local/lib/python2.6/lib-dynload, /usr/local/lib/python2.6/site-packages]



1.7.2 导入模块

1.7.2.1 使用import语句导入模块

有下面两种方式
import module1
import module2
import module3

import module1,module2,module3
这两种方式的效果是一样的,但是第一种可读性比第二种好,推荐按照下面的顺序导入模块,并且一般在文件首部导入所有的模块
python标准库
第三方模块
应用程序自定义模块
也可以在函数内部导入模块,这样被导入的模块作用域是局部的

1.7.2.2 使用from-import语句导入模块的属性
单行导入
from module import name1,name2,name3
多行导入
from module import name1,name2,\
                   name3
导入全部属性(由于容易覆盖当前名称空间中现有的名字,所以一般不推荐使用,适合模块中变量名很长并且变量很多的情况)
from module import *
如果你不想某个模块的属性被以上方法导入,可以给该属性名称前加一个下划线(_test),如果需要取消隐藏,可以显示的导入该属性(from module import _test

1.7.2.3 扩展的import语句
使用自定义的名称替换模块的原始名称
import simplejson as json
模块被导入时,加载的时候模块顶层代码会被执行,如:设定全局变量、类和函数的声明等,所以应该把代码尽量封装到类和函数中。一个模块无论被导入多少次,只加载一次,可以防止多次导入时代码被多次执行。

1.7.2.4 重新导入模块

reload(module)
内建函数reload可以重新导入一个已经存在的模块

1.7.3.结构

1.包定义结构
包将有联系的模块组织在一起,有效避免模块名称冲突问题,让应用组织结构更加清晰。
一个普通的python应用程序目录结构:

app/
__init__.py
a/
__init__.py
a.py
b/
__init__.py
b.py
app是最顶层的包,ab是它的子包,可以这样导入:

from app.a import a
from app.b.b import test

a.test()
test()
上面代码表示:导入app包的子包a和子包b的属性test,然后分别调用test方法。

2. __init__.py的作用
每个目录下都有__init__.py文件,这个是初始化模块,from-import语句导入子包时需要它,可以在里面做一些初始化工作,也可以是空文件。
ps__init__.py定义的属性直接使用 顶层包.子包 的方式导入,如在目录a__init__.py文件中定义init_db()方法,调用如下:
from app import a
a.init_db()

3. 指定python文件编码方式
python默认是使用ASCII编码,可以指定编码方式,如
#!/usr/bin/env python
#coding=utf-8
或者
#!/usr/bin/env python
# -*- coding:utf-8 -*-

4. 解决导入循环问题
有下面两个模块,a.pyb.py
a.py
#!/usr/bin/env python
#coding=utf-8

import b

if __name__ == '__main':
    print 'hello,I'm a'



b.py
#!/usr/bin/env python
#coding=utf-8

import a

if __name__ == '__main':
    print 'hello,I'm b'

在这里a尝试导入b,而b也尝试导入a,导入一个先前没有完全导入的模块,会导致导入失败。解决办法:移除一个导入语句,把导入语句放到函数内部,在需要的时候导入。
b.py
#!/usr/bin/env python
#coding=utf-8

if __name__ == '__main':
    import a
    print 'hello,I'm b'

没有评论:

发表评论

Jurassic World 3" opens in theaters this Friday, 27 dinosaurs set to come, 10 first appearance

 The annual mega-production "Jurassic World 3" will be officially released in China on June 10, and simultaneously landed in IMAX ...