模块让你可以有逻辑地组织Python代码段。把相关的代码分配到一个模块里能让你的代码更好用,更易懂。模块也是Python对象,具备随机的名字属性用来绑定或引用。简单地说,模块就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。python
https://pypi.python.org/pypi/
PyPI(Python Package Index,PyPI) python包索引
为Internet上的第三方Python模块提供一个集中的存储库linux
模块结构和布局:
用模块来合理组织你的 Python 代码是简单又天然的方法。你应该创建一种统一且容易阅读的结构,并将它应用到每个文件中去。
下面就是一种很是合理的布局,一个典型模块的内部结构:shell
# (1) 起始行(Unix) # (2) 模块文档 # (3) 模块导入 # (4) 变量定义 # (5) 类定义 # (6) 函数定义 # (7) 主程序
例:
一个叫作aname的模块里的Python代码通常都能在一个叫aname.py的文件中找到。vim
下例是个简单的模块mod.py:app
[root@wing python]# cat mod.py #!/usr/bin/env python # coding=utf8 ''' 这是一个模块实例 ''' import sys,os name="wing" def hello(): print "hello world" if __name__ =="__main__": hello() 使用模块: In [1]: import mod In [2]: mod.hello() hello world In [4]: print mod.__doc__ 这是一个模块实例 In [5]: print mod.name wing
查询模块是内建模块仍是属于某一个模块文件python2.7
In [5]: __import__("sys") Out[5]: <module 'sys' (built-in)> In [3]: __import__("os") Out[3]: <module 'os' from '/usr/lib64/python2.7/os.pyc'> In [4]: __import__("os").__file__ Out[4]: '/usr/lib64/python2.7/os.pyc'
可使用两种方法调用main函数,可是每次在python解释器里第一次import模块pysysinfo_func时都会执行main函数若是又想能够把模块当脚本同样在命令行总体执行,又想在其余脚本调用模块内单独的某一个函数,可使用第二种方式编辑器
#vim pysysinfo_func.py #!/usr/bin/env python import subprocess def uname_func(): uname = "uname" uname_arg = "-a" print "Gathering system information with %s command:\n" % uname subprocess.call([uname,uname_arg]) def disk_func(): diskspace = "df" diskspace_arg = "-Th" print "Gathering diskspace information with %s command:\n" % diskspace subprocess.call([diskspace,diskspace_arg]) def main(): uname_func() disk_func() #第一种方式: main() #第二种方式: if __name__ == "__main__": main() 第一种方式的结果以下:会在导入模块的时候执行main函数 In [1]: import pysysinfo_func Gathering system information with uname command: Linux vm2.up.com 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64 x86_64 x86_64 GNU/Linux Gathering diskspace information with df command: Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root ext4 18G 4.1G 13G 25% / tmpfs tmpfs 565M 224K 565M 1% /dev/shm /dev/sda1 ext4 485M 34M 427M 8% /boot /dev/sr0 iso9660 3.5G 3.5G 0 100% /mnt 第二种方式的结果以下: In [1]: import pysysinfo_func //不会在导入模块的时候执行main函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ python中__name__的使用 1. 若是模块是被导入,__name__的值为模块名字 2. 若是模块是被直接执行,__name__的值为’__main__’ Py1.py #!/usr/bin/env python def test(): print '__name__ = ',__name__ if __name__ == '__main__': test() Py2.py #!/usr/bin/env python import Py1.py def test(): print '__name__ = ',__name__ if __name__ == '__main__': test() print ‘Py1.py __name__ = ’,Py1.__name__ 执行结果: __name__=__main__ Py1.py __name__=Py1 经过结果能够知道,Py2.py直接执行,那么内建变量__name__的值为__main__,不然为 模块的名字,经过这个特性能够 在if语句里面添加测试代码,能够提升减小BUG,提升程序的健壮性。 if __name__ == '__main__': test()
经过查看模块存放路径就知道咱们本身制做的模块应该放在哪一个位置ide
查看python默认的模块存放路径。 函数
>>> import sys >>> sys.path ['', '/usr/local/python27/lib/python27.zip', '/usr/local/python27/lib/python2.7', '/usr/local/python27/lib/python2.7/plat-linux2', '/usr/local/python27/lib/python2.7/lib-tk', '/usr/local/python27/lib/python2.7/lib-old', '/usr/local/python27/lib/python2.7/lib-dynload', '/usr/local/python27/lib/python2.7/site-packages'] >>>
列表内的第一个元素''表示当前工做目录,也就是说模块在当前目录下也可以使用默认存放模块的目录是:/usr/local/python27/lib/python2.7/布局
dir()函数
dir()函数返回一个排好序的字符串列表,内容是一个模块里定义过的名字。
返回的列表容纳了在一个模块里定义的全部模块,变量和函数。
实例:
#!/usr/bin/python import math content = dir(math) print content; 输出结果: ['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
在这里,特殊字符串变量name指向模块的名字,file指向该模块的导入文件名。
想使用Python模块,只需在另外一个源文件里执行import语句
语法以下:
import module1[, module2[,... moduleN]
当解释器遇到import语句,若是模块在当前的搜索路径就会被导入。
搜索路径:
是一个解释器会先进行搜索的全部目录的列表。如想要导入模块support.py,须要把命令放在脚本的顶端
#!/usr/bin/python # -*- coding: UTF-8 -*- # 导入模块 import support # 如今能够调用模块里包含的函数了 support.print_func("Zara") 以上实例输出结果: Hello : Zara
一个模块只会被导入一次,无论你执行了多少次import。这样能够防止导入模块被一遍又一遍地执行。
Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。语法以下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块fib的fibonacci函数,使用以下语句:
from fib import fibonacci
这个声明不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入到执行这个声明的模块的全局符号表。
把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的全部项目。然而这种声明不应被过多地使用。
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
• 当前目录 • 若是不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每一个目录。 • 若是都找不到,Python会察看默认路径。UNIX下,默认路径通常为/usr/local/lib/python/。
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
PYTHONPATH变量
做为环境变量,PYTHONPATH由装在一个列表里的许多目录组成。PYTHONPATH的语法和shell
变量PATH的同样。
在Windows系统,典型的PYTHONPATH以下:
set PYTHONPATH=c:\python20\lib
在UNIX系统,典型的PYTHONPATH以下:
set PYTHONPATH=/usr/local/lib/python
正常状况下使用python解释器,使用模块的方法时须要导入模块,一些本身比较经常使用的模块好比os、process每次开始python解释器都得从新调用,下面的方法能够为你解除痛苦。
很是简单,只需设置一个变量,变量的值为某个.py文件的路径,在.py文件内设置预先想要导入的模块
# export PYTHONSTARTUP=/a.py # cat /a.py import os import subprocess [root@vm2 ~]# python >>> os.system("ls") //能够看到测试的OS模块的时候能够直接使用,无需事先导入 模块OS anaconda-ks.cfg Documents install.log.syslog Public a.py Downloads Music Templates 咱们能够利用上面得方法把tab键功能写入模块内事先导入
reload()函数
当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次。所以,若是你想从新执行模块里顶层部分的代码,能够用reload()函数。该函数会从新导入以前导入过的模块。
语法以下:
reload(module_name)
在这里,module_name要直接放模块的名字,而不是一个字符串形式。
好比想重载hello模块,以下:
reload(hello)
1.同一个模块导入,第一次代码所有运行,第二次不少的代码都不运行的,其实中间只是重复执行 2.尝试在第一次导入后,修改源文件,而后第二次导入,结果跟第一次同样。
缘由:
导入操做的开销很是大,它把文件先编译成字节码,而后再导pvm(python virtual machine)上去执行,在编译的过程当中,消耗资源很是多,因此,导入操做只编译执行一次,第二次只是重复执行,再也不编译。 若是想再次执行完整的代码,就须要reload()这个函数,他会把源代码从新载入,而后执行一遍,可是在执行reload前,必须保证已经import那个模块。 注意:在python3里,执行reload前,请先执行from imp import reload,由于reload在python3里已经再也不是内置函数。
例:
1.编写模块a.py #!/usr/bin/env python print "hello world" 2.进入Ipython倒入模块 In [1]: import a hello world 第一次导入结果有输出 In [2]: import a 第二次导入结果就没有输出了 In [3]: import a 修改源文件后再次导入仍然没有输出结果 In [4]: 必须的用reload()重载模块才行
以以前处理嵌套列表的代码为例,把他作成能够发给别人使用的模块
1.建立父目录:
#mkdir /nester
2.准备源代码文件:
#vim /nester/nester.py
#!/usr/bin/env python
#coding=utf-8
"这是模块文档字符串"
def print_list(name):
"这是函数文档字符串"
for each_item in name:
if isinstance(each_item,list):
print_list(each_item)
else:
print each_item
3.准备setup.py文件:
#!/usr/bin/env python from distutils.core import setup setup( name = 'nester', version = '1.0.0', py_modules = ['nester'], author = 'wing', author_email = '276267003@qq.com', url = 'www.fklinux.com', description = 'A simple printer of nested lists', )
4.构建发布文件:
# python setup.py sdist
5.构建成功以后/nester目录下会出现dist目录,dist目录下会出现构建好的模块打包文件,这个文件就能够发给别人使用了
[root@host nester]# ls dist/
nester-1.0.0.tar.gz
6.测试安装模块:
#tar xvzf nester-1.0.0.tar.gz
#cd nester-1.0.0
#python setup.py install
#python
import nester //其实到这里,若是你能导入模块成功的话,恭喜你,^_^说明你的模块儿没问题了,下面是这个模块的具体使用
a=[1,2,3,[4,5,[6,7]]]
nester.print_list(a)
1
2
3
4
5
6
7Python中的包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境。
例子:
1.建立目录Phone,做为包名 #mkdir /Phone 2.分别建立模块文件pots.py、lsdn.py和G3.py #cat /Phone/pots.py #!/usr/bin/python def Pots(): print "I'm Pots Phone" #cat /Phone/Isdn.py #!/usr/bin/python def Lsdn(): print "I'm lsdn Phone" #cat /Phone/G3.py #!/usr/bin/python def G3(): print "I'm G3 Phone" 3.在/Phone目录下建立文件 __init__.py: #cat /Phone/__init__.py from Pots import Pots from Isdn import Isdn from G3 import G3 4.使用包: #!/usr/bin/python # 导入 Phone 包 import Phone Phone.Pots() Phone.Isdn() Phone.G3() 输出结果: I'm Pots Phone I'm 3G Phone I'm ISDN Phone 如上,为了举例,只在每一个文件里放置了一个函数,但其实你能够放置许多函数。你也能够在这些文件里定义Python的类,而后为这些类建一个包。
若是在python编辑器里tab键不能补全,能够本身定义一个tab.py程序,而后看成模块导入就可使用tab键补全了
#cat tab.py #!/usr/bin/env python import sys,readline,rlcompleter,os readline.parse_and_bind('tab: complete') histfile = os.path.join(os.environ['HOME'],'.pythonhistory')
把本身编写的tab模块拷贝到默认模块目录下,若是不拷贝到默认位置也可使用,不过须要在进入python shell的当前目录下存放tab.py
#mv tab.py /usr/local/python27/lib/python2.7/
tab模块使用:
import tab
上面的方式在使用tab模块的时候跟使用其余模块同样每次都须要手动导入,若是你像我同样比较懒^_^,可使用下面的方法,在启动python shell的时候就自动导入咱们想让他导入的模块
1.建立一个脚本文件:
#!/usr/bin/evn python import tab print "module loaded"
2.设置PYTHONSTARTUP环境变量:
#export PYTHONSTARTUP=/root/.startup.py //如何永久生效?你懂的
3.测试:
Python 2.7.10 (default, Dec 13 2016, 10:54:54) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2 Type "help", "copyright", "credits" or "license" for more information. module loaded