Python3 模块
在Python中模块的后缀为.py文件,它是一个包含所有与该模块相关联的函数与变量的文件,模块可以保存,也可以被其它程序引入,这也是使用Python标准库的方法,在Python的标准安装中包含了一组自带的模块,这些模块被称为标准库;
不仅如此,Python的开发者们可以根据需要不断扩充模块,各行各业的Python用户也贡献了大量的Python拓展库,它们大大拓展了Python的功能,这也是Python日益强大的一个不可忽略的原因;
一.如何导入模块:
1.自定义一个模块:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a simple try'
__author__ = 'william'
def add(a,b):
print('两数之和为:%d' % (a+b))
在这个例子中,我写了一个非常简单的add模块,并保存文件格式为 add.py,其中,它的前两行是标准注释,第一行注释可以让这个add模块文件直接在Linux/Unix/Mac上运行,第二行注释表示.py文件本身使用标准UTF-8编码;接下来第三行是为这个模块添加的字符串注解说明,就像在函数里面添加的那个差不多,不管任何模块它的第一行字符串都会被视为注解说明,之后第四行则是这个模块编写者的名字,用__anthor__变量存入;
之后第六行才是模块的主体部分,即一个函数,模块其实封装的就是一个又一个的函数,在这之前的所有工作其实你都可以不做,只要有完整的函数那么这个模块导入之后就可以正常的发挥作用;
模块定义好了之后,就可以导入并使用它了,这里我又创建了一个文件,在该文件内导入add模块:
2.导入模块
import add as a
a.add(3,9)# 两数之和为:12
简单分析一下这两条语句,Python里面用import语句导入模块,注意导入时候import后面跟的是模块名,在导入时你也可以用 as 给该模块指定别名,当然你也可以不指定;执行import语句时,Python会读取add文件并将其中所有的函数都复制到当前程序内,你看不到这些代码,因为在程序运行时,Python在幕后进行这些工作;
现在我已经导入了自定义模块add并通过指定别名获得了变量a,a指向add模块,通过a可以使用里面的所有函数,于是调用add模块里面的add()函数,成功输出;
<小问题>
这里我在实现时其实遇到了一个小问题,也一并分享:
最开始我的导入代码是这样的:
import add as a
print(a.add(3,9))
#然后输出是这样的:
两数之和为:12
None
输出有两行,第一行是我想要的,可第二行莫名其妙地输出了一个None是怎么回事?而且无论我怎么更换数据,更换方法,只要输出就伴随着None出现;
在网上搜了一下,发现原来是print()函数多输出了一次…
其实是这样的,我的add模块里面的add()函数没有返回值,函数没有返回值Python默认返回None,而又因为我的add()函数里面本就有print语句,而我在调用时又用了print,相当于输出了两次,第一次输出了正常结果,第二次输出的是add()函数的返回值None;
3.import的多种语法
以导入sys模块为例,sys模块负责Python解释器与程序的交互,并且提供了一系列的函数和变量,用于操作Python运行时的环境;现在来导入它:
导入特定函数:
from sys import argv #导入sys模块的argv成员
from sys import argv as a #导入argv并指定别名a
这种导入方法导入的函数可以直接用,不需要使用句点;
导入模块所有函数:
from sys import *
这种导入方法并不推荐,尤其是在使用并非自己编写的大型模块时;
另外注意,一个模块只会被导入一次,不管你执行了多少次import,这样可以防止导入模块重复执行;
4.一个例子
自定义一个简单模块,文件名为mess,如下:
#mess.py
print('hello,world')
def hello():
print('hello,python')
接着我们导入它:
import mess as m
m.hello()
#运行结果:
hello,world
hello,python
接着我们只导入hello函数再试一次:
from mess import hello
hello()
#运行结果:
hello,world
hello,python
应该已经发现了,无论是导入整个模块,还是只导入特定函数,模块内的第一行print语句总被执行,这说明哪怕是在导入特定函数时,Python依然会加载并执行模块中的所有代码;
其实,导入模块的本质就是把该模块的所有代码全部加载到内存并执行,然后制定一个变量,如果导入的是整个模块,那么这个变量就是module型,而在模块中定义的所有程序单元都相当于该module对象的成员,如果导入的是指定函数,那么就会只导入指定变量、函数等成员,并不导入整个模块;
5.__name__属性
每个模块都有一个__name__属性,当模块未被导入时,它的值是__main__,否则则表明模块已被导入;
例:
if __name__ == '__main__':
print('hello,world')
else:
print('hello,python')
#在自身文件内运行:
hello,world
#导入后:
import mess
hello,python
6.__all__变量用法
如果采用 from module import * 这种用法来导入模块的话,通常会导入模块内所有成员单位,但如果该模块定义了__all__变量,那么这种方法就只能导入__all__规定可以导出的成员单位,定义__all__时用定义列表的方法即
all = [] 来划分成员单位,在这个列表之内的成员都可以被导出,但之外的就无法被导出,也无法被使用;
但如果确实想使用__all__规定之外的成员也可以,不用这种 * 导入法就ok:
import module
from module import 成员
以上两种总可以导入__all__规定之外的成员;
二.包
1.什么是包
为了更好的管理多个模块源文件,Python提供了包的概念,包其实就是一个文件夹,这个文件夹里面存放了很多模块,除此之外还有一个__init__.py文件,包的本质依然是模块,因此包也可以包含子包;
Python采用“点模块名称”来使用包中的模块,这样也可以避免不同的包之间重名的情况,比如,A.B就表示A包下的B模块;导入包的方法与导入模块一样;
2.创建一个包
一个包里面必须包含一个 init.py 文件,下面来创建一个包:
首先我们创建一个文件夹,文件夹的名字就是包的名字,然后在该文件夹内创建一个__init__.py文件,之后就可以编写包内的模块了,这里我创建了一个f_package的包;
#add.py
def add(a,b):
print('两数之和为%d' % (a+b))
#sub.py
def sub(a,b):
print('两数之差为%d' % (a-b))
#mul.py
def mul(a,b):
print('两数相乘为%d' % (a*b))
#div.py
def d,iv(a,b):
if b == 0:
print('error')
else:
print('两数相除为%d' % (a/b))
f_package里面有5个文件,除却__init__.py之外,还有四个如上所示的模块,每个模块完成一项简单的加减乘除操作,十分简单,调用它们时可以这样:
import f_package.mul
f_package.mul.mul(8,9)# 两数相乘为72
于是你可能发现了一些问题,在这个包里面,init.py 是一个空文件,并没有用到,而且在使用包中的模块内函数时,一层一层的用句点也未免太过麻烦;
其实__init__.py文件的作用就是导入该包内模块的成员,即把包内模块内的成员变成包内成员,这样使用起来就会更加方便;
具体操作是这样:
打开__init__.py文件编辑:
from . import add #从当前包内导入add模块
from .add import * #从add模块中导入所有成员到包中
之后再使用add包时,就方便了一些:
import f_package as f
f.add(9,8) #两数之和为17
这只是导入了一个模块内的成员,根据需要可以选择性导入;
另外包里面也可以定义__all__变量,定义在__init__.py文件内;
部分内容(不限于本文)参考自: