# 模块
前面提到的函数是一种模块化编程,它将一个功能包装为一个函数,在需要的时候调用它,这里说的模块更像是一个文件夹,它有很多文件,每个文件里很多函数,通过导入这个模块就能使用这里面的函数。Python包含了一组自带的模块,它们被称为标准库,它们为Python提供了很多功能。
# 导入模块
它有两种语法,一种是将模块整个导入,另一种是导入模块的某个函数。
import sys as MySys,random as MyRandom
print(MySys.argv)
print(MyRandom.random())
from time import *
print(gmtime())
from random import random
print(random())
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 定义模块
我们可以定义自己的模块,前面我们自己写的所有Python程序都可作为模块导入,作为模块导入的好处是这些模块可以被重复使用:
PersonModule.py文件内容:
'''
这是一个我们自己定义的模块
Person:这是一个模板类
'''
class Person:
def Walk(self):
print("He is walking!")
def Eat(self):
print("He is eatting!")
def test_person_walk():
p = Person()
p.Walk()
def test_person_eat():
p = Person()
p.Eat()
if __name__=='__main__':
test_person_walk()
test_person_eat()
print("__name__:%s" % __name__)
print("Person module is imported!")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
定义一个模块要做的事情:
- 编写说明文档。
- 编写模块主程序。
- 编写测试程序。
注意当上面的模块被python直接运行时,此时__name__是'main',这个时候测试程序才会运行,否则当模块作为模块被导入时,是不会运行测试程序的。
# 加载模块
下面来加载这个模块,在与PersonModule.py同一个文件夹的另一个文件中:
import PersonModule
p = PersonModule.Person()
p.Walk()
from PersonModule import Person
p2 = Person()
p2.Eat()
print(PersonModule.__doc__)
import sys,pprint
#查看Python的默认模块加载路径
pprint.pprint(sys.path)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
注意:
- 在import的时候Python是根据环境变量PYTHONPATH来查找模块的,这些变量默认都会包含当前目录。
- 使用import导入模块,是把模块中的全部代码加载到内存并执行,然后将整个模块内容赋给与模块文件名同名的变量,该模块中定义的所有程序单元都相当于该变量的成员;使用from...import导入模块,把模块中的全部代码加载到内存,然后只导入指定变量,函数等成员。
- 不管使用何种方式导入,导入模块的时候,模块中的代码都会运行一遍,重复导入,只运行一次。
- 在模块文件夹下有__pycache__文件夹,其中有pyc文件,该文件其实是为模块编译生成的字节码,用于提升该模块的运行效率。
# __all__变量
默认情况下,使用from 模块名 import * 这个语句来导入模块,会导入该模块中所有不以双下划线开头的程序单元,而__all__变量则是设置一个列表,这个列表之外的单元都不会被暴露。如果想要导入列表之外的部分,可以:
- 使用import 模块名,来导入模块。
- 使用from 模块名 import 程序单元,来导入指定程序单元。
'''
测试__all__变量
'''
def test1():
print("this is test1")
def test2():
print("this is test2")
def test3():
print("this is test3")
__all__=["test1","test2"]
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
测试__all__变量:
from PersonModule import *
test1()
#import PersonModule
#PersonModule.test3()
from PersonModule import test3
test3()
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 包
前面的模块只是一个文件,包是一个文件夹,在该文件夹下包含了一个__init__.py文件,由该文件再包含它包里面的其他文件,当外部导入一个包时,就导入了这个包里的所有文件。
# 定义包
在一个MyPackage文件夹下,__init__.py文件内容:
'''
这是定义的第一个包。
'''
#from . import Student
from .Student import *
#from . import Person
from .Person import *
1
2
3
4
5
6
7
2
3
4
5
6
7
Student.py文件内容:
def student():
print("this is a student activity!")
1
2
2
Person.py文件内容:
def Eat():
print("I am eatting!")
def Walk():
print("I am walking!")
1
2
3
4
2
3
4
跳出这个文件夹,开一个测试文件:
import MyPackage
MyPackage.Walk()
MyPackage.Eat()
MyPackage.Student.student()
print(MyPackage.__doc__)
#查看包的位置
print(MyPackage.__file__)
print(dir(MyPackage))
print([e for e in dir(MyPackage) if not e.startswith("__")])
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
注意在__init__.py文件中只有from .Student import *,也可以在导入包时使用MyPackage.Student.方法名。