CrazyWing:Python自动化运维开发实战 十五、Python模块

简介:

导语:

模块让你能够有逻辑地组织Python代码段。把相关的代码分配到一个模块里能让你的代码更好用,更易懂。模块也是Python对象,具有随机的名字属性用来绑定或引用。简单地说,模块就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。

相关站点:

https://pypi.python.org/pypi/
PyPI(Python Package Index,PyPI) python包索引
为Internet上的第三方Python模块提供一个集中的存储库

制作模块

模块结构和布局:
用模块来合理组织你的 Python 代码是简单又自然的方法。你应该建立一种统一且容易阅读的结构,并将它应用到每一个文件中去。
下面就是一种非常合理的布局,一个典型模块的内部结构:

    # (1) 起始行(Unix) 
    # (2) 模块文档
    # (3) 模块导入
    # (4) 变量定义
    # (5) 类定义
    # (6) 函数定义
    # (7) 主程序

例:
一个叫做aname的模块里的Python代码一般都能在一个叫aname.py的文件中找到。

下例是个简单的模块mod.py:

[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

import():

查询模块是内建模块还是属于某一个模块文件

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'

内建变量name

可以使用两种方法调用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()

查看模块:

查看模块存放位置

通过查看模块存放路径就知道我们自己制作的模块应该放在哪个位置

查看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指向该模块的导入文件名。

调用模块

import 语句

想使用Python模块,只需在另一个源文件里执行import语句
语法如下:
import module1[, module2[,... moduleN] 
当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。

搜索路径:
是一个解释器会先进行搜索的所有目录的列表。如想要导入模块support.py,需要把命令放在脚本的顶端

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    # 导入模块
    import support 
    # 现在可以调用模块里包含的函数了
    support.print_func("Zara") 

以上实例输出结果:
    Hello : Zara 
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。

From…import 语句

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块fib的fibonacci函数,使用如下语句:
from fib import fibonacci
这个声明不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入到执行这个声明的模块的全局符号表。

From…import * 语句

把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明: 
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解释器开启时调用模块

正常情况下使用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文件:

vim /nester/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.构建发布文件:

cd /nester

    # 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
7

Python中的包

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的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的类,然后为这些类建一个包。

制作tab补全模块:

如果在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的时候就自动导入我们想让他导入的模块

python shell自动导入模块:

1.创建一个脚本文件:

cat /root/.startup.py

    #!/usr/bin/evn python
    import tab
    print "module loaded"

2.设置PYTHONSTARTUP环境变量:
#export PYTHONSTARTUP=/root/.startup.py //如何永久生效?你懂的

3.测试:

python

    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
本文转自 CrazyWing 51CTO博客,原文链接:http://blog.51cto.com/fklinux/2050113
相关文章
|
6天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
16天前
|
存储 开发者 Python
Python中的collections模块与UserDict:用户自定义字典详解
【4月更文挑战第2天】在Python中,`collections.UserDict`是用于创建自定义字典行为的基类,它提供了一个可扩展的接口。通过继承`UserDict`,可以轻松添加或修改字典功能,如在`__init__`和`__setitem__`等方法中插入自定义逻辑。使用`UserDict`有助于保持代码可读性和可维护性,而不是直接继承内置的`dict`。例如,可以创建一个`LoggingDict`类,在设置键值对时记录操作。这样,开发者可以根据具体需求定制字典行为,同时保持对字典内部管理的抽象。
|
22天前
|
Web App开发 Python
在ModelScope中,你可以使用Python的浏览器自动化库
在ModelScope中,你可以使用Python的浏览器自动化库
15 2
|
17天前
|
存储 缓存 算法
Python中collections模块的deque双端队列:深入解析与应用
在Python的`collections`模块中,`deque`(双端队列)是一个线程安全、快速添加和删除元素的双端队列数据类型。它支持从队列的两端添加和弹出元素,提供了比列表更高的效率,特别是在处理大型数据集时。本文将详细解析`deque`的原理、使用方法以及它在各种场景中的应用。
|
3天前
|
Python
python学习14-模块与包
python学习14-模块与包
|
4天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
8天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
9天前
|
JSON 测试技术 持续交付
自动化测试与脚本编写:Python实践指南
【4月更文挑战第9天】本文探讨了Python在自动化测试中的应用,强调其作为热门选择的原因。Python拥有丰富的测试框架(如unittest、pytest、nose)以支持自动化测试,简化测试用例的编写与维护。示例展示了使用unittest进行单元测试的基本步骤。此外,Python还适用于集成测试、系统测试等,提供模拟外部系统行为的工具。在脚本编写实践中,Python的灵活语法和强大库(如os、shutil、sqlite3、json)助力执行复杂测试任务。同时,Python支持并发、分布式执行及与Jenkins、Travis CI等持续集成工具的集成,提升测试效率和质量。
|
9天前
|
索引 Python
「Python系列」Python operator模块、math模块
Python的`operator`模块提供了一系列内置的操作符函数,这些函数对应于Python语言中的内建操作符。使用`operator`模块可以使代码更加清晰和易读,同时也能提高性能,因为它通常比使用Python内建操作符更快。
27 0
|
12天前
|
jenkins 测试技术 持续交付
软件测试|docker搭建Jenkins+Python+allure自动化测试环境
通过以上步骤,你可以在Docker中搭建起Jenkins自动化测试环境,实现Python测试的自动化执行和Allure报告生成。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
32 6

热门文章

最新文章