模块(Module)简介
我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,
那么你定义的所有的方法和变量就都消失了。为此 Python 提供了一个办法,
把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
模块的定义:
模块是一个包含所有定义的函数和变量的文件,其后缀名是.py。
模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
使用模块的好处:
1、提高了代码的可维护性。
2、编写代码不需要从零开始,当一个模块编写完毕,就可以被其他地方引用。
我们编写程序的时候经常引用其他模块,包括Python内置的模块和来自第三方的模块。
查看模块位置:
模块名.__file__
示例1:
In [1]: import os
In [2]: os.__file__
Out[2]: '/usr/local/lib/python3.7/os.py'
示例2:
In [3]: import psutil
In [4]: psutil.__file__
Out[4]: '/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil/__init__.py'
#进入目录查看
In [7]: cd /usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil/
/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil
In [8]: ls
_common.py _pslinux.py _psutil_linux.cpython-37m-x86_64-linux-gnu.so* _pswindows.py
_compat.py _psosx.py _psutil_linux.py __pycache__/
__init__.py _psposix.py _psutil_posix.cpython-37m-x86_64-linux-gnu.so*
_psbsd.py _pssunos.py _psutil_posix.py
模块的意义
模块就好比是工具包,要想使用这个这个工具包中的工具(就好比函数),就需要导入这个模块
示例:
vim sendmsg.py #创建模块
def test1():
print("--sendmsg-test1--")
def test2():
print("--sendmsg-test2--")
vim main.py #创建新模块并导入之前创建的模块
import sendmsg
sendmsg.test1()
sendmsg.test2()
python3 main.py #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--
前提:两个模块必须在同一个目录下否则不能进行调用
莫夸引用后会产生一个目录文件:__pycache__
[root@localhost py]# tree __pycache__/
__pycache__/
└── sendmsg.cpython-37.pyc #sendmsg是引用的模块名,cpython代表用c写的解析器
#37代表python版本3.7,.pyc是python的自解码文件
0 directories, 1 file
模块的引用
模块名.函数名
示例:
sendmsg.test1()
引入方式的改变
有时候只需要用到模块中的某个函数,只需要引入该函数即可:
form 模块名 import 函数名1,函数名2.....
导入某个模块的函数
语法:
from modname import name1,name2,..nameN
示例1:
vim sendmsg.py #创建模块
def test1():
print("--sendmsg-test1--")
def test2():
print("--sendmsg-test2--")
vim main.py #创建新模块并导入之前创建的模块
from sendmsg import test1,test2
test1()
test2()
python3 main.py #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--
示例2: #不建议使用此方式
vim sendmsg.py #创建模块
def test1():
print("--sendmsg-test1--")
def test2():
print("--sendmsg-test2--")
vim main.py #创建新模块并导入之前创建的模块
from sendmsg import *
test1()
test2()
python3 main.py #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--
使用as起别名
意义:当模块名字过长时起一个短一些的别名会方便许多
示例:
In [1]: import time as tt
In [2]: tt.sleep(3)
在程序中模块是怎样加载的
In [3]: import sys #导入外部模块
In [4]: sys.path #想查看文件搜索路径
Out[4]:
['/usr/local/bin',
'/usr/local/lib/python37.zip',
'/usr/local/lib/python3.7',
'/usr/local/lib/python3.7/lib-dynload',
'',
'/usr/local/lib/python3.7/site-packages',
'/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg',
'/usr/local/lib/python3.7/site-packages/IPython/extensions',
'/root/.ipython']
# /root/.ipython只有在ipython中才加载此目录中的内容,其他地方不回加载。
#'' 代表当前工作目录,从哪个目录下进入的ipython哪个目录就是所载工作目录。
#当模块放入以上任何一个位置都是可以搜索到的,都可以在ipython中直接使用
__all__变量:
如果一个文件中有__all__变量,name也就意味着这个变量中的元素,
会被from xxx import * 时导入
当有些功能不想让别人使用的时候就可以使用这种方式。
示例:
vim test.py #创建新的模块
num = 100
def test1():
print("test模块中的test1函数...")
def test2():
print("test模块中的test2函数...")
class Person(object):
age = 18
def __init__(self,name):
self.name = name
def __str__(self):
msg = "%s的年龄是:%s"%(self.name,Person.age)
return msg
if __name__ == '__main__':
test1()
test2()
p = Person("张三")
print(p)
vim main2.py #创建新模块并导入之前创建的模块
from test import *
print(num)
test1()
test2()
p = Person("李四")
print(p)
python3 main2.py ##执行并查看模块导入后运行的结果
100
test模块中的test1函数...
test模块中的test2函数...
李四的年龄是:18
if __name__ == '__main__':
#测试方法,在其他模块引入时不会影响其他模块运行(此部分不会被其他模块所引用)
示例2:
vim test.py #创建新的模块
__all__ = ('num','test1','Person') #只允许调用括号内的内容
num = 100
def test1():
print("test模块中的test1函数...")
def test2():
print("test模块中的test2函数...")
class Person(object):
age = 18
def __init__(self,name):
self.name = name
def __str__(self):
msg = "%s的年龄是:%s"%(self.name,Person.age)
return msg
if __name__ == '__main__':
test1()
test2()
p = Person("张三")
print(p)
vim main2.py #创建新模块并导入之前创建的模块
from test import *
print(num)
test1()
test2()
p = Person("李四")
print(p)
python3 main2.py #查看结果
100
test模块中的test1函数...
Traceback (most recent call last):
File "main2.py", line 4, in <module>
test2()
NameError: name 'test2' is not defined
vim main2.py #创建新模块并导入之前创建的模块
from test import *
import test #当以这种方法调用时不受__all__限制
print(num)
test1()
test.test2()
p = Person("李四")
print(p)
[root@localhost py]# python3 main2.py
100
test模块中的test1函数...
test模块中的test2函数...
李四的年龄是:18
总结:
可以限制from test import * 导入时那些模块可以使用,不能使用未写在括号内的模块
但是import test这种调用方式不受__all__
#__all__只能限制from test import * 调用模式下的模块
模块的制作
定义自己的模块
在python中,每个python文件都可以作为一个模块,模块的名字就是文件的名字。
比如有一个文件test.py,在test.py中定义了函数add
调用自己的函数
使用__name__测试模块
示例:
vim test.py
def add(a,b):
return a+b
def add2(a,b,opt):
#a和b是两个数,opt是匿名函数
result = opt(a,b)
return result
if __name__ =='__main__':
a = add(100,200)
print("a+b=%s"%a)
result = add2(100,200,lambda x,y:x*y)
print("使用匿名函数计算:100*200=%s"%result)
[root@localhost test]# python3 test.py
a+b=300
使用匿名函数计算:100*200=20000
创建一个脚本进行调用
vim main.py
import test
a = test.add(100,200)
print("a+b=%s"%a)
result = test.add2(100,200,lambda x,y:x*y)
print("使用匿名函数计算:100*200=%s"%result)
测试:
[root@localhost test]# python3 main.py
a+b=300
使用匿名函数计算:100*200=20000
定义
包将有联系的模块组织在一起,即放在同一个文件夹下,并且在这个文件夹创建一个名字为
__init__.py的文件,那么这个文件夹就称之为包
一般情况下:__init__py文件不只是限制文件的导入,还可以做一些初始化操作
__all__在包中的作用:
在__init__.py文件中,定义一个__all__变量,它控制着from包名import *时导入的模块
可以在__init__.py文件中编写内容
示例1:
ipython
import 包名.模块名
包名.模块名.函数名()
示例2:只导入包名 #需要在__init__.py文件中写入__all__['模块名','模块名']
from 包名 import *
模块名.函数名()
包的好处
可以有效的避免模块名冲突的问题
嵌套的包
1. 目录结构
假定我们的包的例子有如下的目录结构:
Phone/
__init__.py
common_util.py
Voicedta/
__init__.py
Pots.py
Isdn.py
Fax/
__init__.py
G3.py
Mobile/
__init__.py
Analog.py
igital.py
Pager/
__init__.py
Numeric.py
2. 导入子包和使用模块
Phone 是最顶层的包,Voicedta 等是它的子包。 我们可以这样导入子包:
import Phone.Mobile.Analog
Phone.Mobile.Analog.dial()
3. 你也可使用 from xxx import xxx 实现不同需求的导入
第一种方法是只导入顶层的子包,然后使用属性/点操作符向下引用子包树:
from Phone import Mobile
Mobile.Analog.dial('555-1212')
此外,我们可以还引用更多的子包:
from Phone.Mobile import Analog
Analog.dial('555-1212')
事实上,你可以一直沿子包的树状结构导入:
from Phone.Mobile.Analog import dial
dial('555-1212')
在我们上边的目录结构中,我们可以发现很多的 __init__.py 文件。这些是初始化模块,
from-import 语句导入子包时需要用到它。 如果没有用到,他们可以是空文件。
4. 包同样支持 from xxx import *
包同样支持 from-import all 语句:
from package.module import *
然而,这样的语句会导入哪些文件取决于操作系统的文件系统。
所以我们在__init__.py 中加入 __all__ 变量。
该变量包含执行这样的语句时应该导入的模块的名字。它由一个模块名字符串列表组成。
模块的安装
打包模块
msg目录结构
msg
__init__py
money
__init__py
msgmoney.py
recvmsg.py
sendmsg.py
setup.py
生成发布压缩包:
python setup.py
模块安装、使用:
1、解压 tar -zxvf xxx.tar.gz
2、进入文件夹
3、执行安装命令 sudo python setup.py install
4、指定安装位置:python setup.py install --prefix = 指定安装位置
使用安装好的模块:
在程序中,使用from import即可完成对安装的模块使用 from 模块名 import 模块名或者*
模块知识扩展
常用模块简介
Python有一套很有用的标准库(standard library)。标准库会随着Python解释器,
一起安装在你的电脑中的。 它是Python的一个组成部分。
这些标准库是Python为你准备好的利器,可以让编程事半功倍。
1. 常用标准库
标准库 | 说明 |
builtins | 内建函数默认加载 |
os | 操作系统接口 |
sys | Python自身的运行环境 |
functools | 常用的工具 |
json | 编码和解码 JSON 对象 |
logging | 记录日志,调试 |
multiprocessing | 多进程 |
threading | 多线程 |
copy | 拷贝 |
time | 时间 |
datetime | 日期和时间 |
calendar | 日历 |
hashlib | 加密算法 |
random | 生成随机数 |
re | 字符串正则匹配 |
socket | 标准的 BSD Sockets API |
shutil | 文件和目录管理 |
glob | 基于文件通配符搜索 |