Python——模块
一、模块的介绍
1.1 什么是模块
模块就是一系列功能的集合体,分为三大类
-
1.1.1 内置的模块
-
1.1.2 第三方模块
-
1.1.3 自定义模块
- 一个python文件本身就是一个模块,文件名m.py,模块名叫m
-
了解:模块分为四种形式
''' 1、使用python编写的.py文件 2、已被编译为共享库或DLL的c或c++扩展 3、把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包) 4、使用c编写并链接到python解释器的内置模块 '''
1.2 为何要有模块
- 内置与第三方的模块拿来就用,无需定义,可以极大的提升自己的开发效率
- 自定义模块:可以将程序的各部分功能提取出来放到一个模块中为大家共享使用,减少代码冗余,程序组织结构更加清晰
二、模块的使用
2.1 import语句
import 模块名
# 1、首次导入模块会发生3件事
# 1、执行foo.py
# 2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中
# 3、在当前文件中产生的有一个名字foo,该名字指向2中产生的名称空间
# 之后的导入,都是直接引用首次导入产生的foo.py名称空间,不会重复执行代码(即不会重复导入同一模块)
# 2、引用:
# print(foo.x)
# print(foo.get)
# print(foo.change)
# 强调1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突
# 强调2:无论是查看还是修改操作的都是模块本身,与调用位置无关
# 3、可以以逗号为分隔符在一行导入多个模块(不建议在一行同是导入多个模块)
# 4、导入模块的规范
#I. python内置模块
#II. 第三方模块
#III. 程序员自定义模块
import time
import sys
import 第三方1
import 自定义模块1
# 5、import 。。。 as 。。。
import foo as f # f=foo
f.get()
# 6、模块是第一类对象
# 7、自定义模块的命名应该采用纯小写+下划线的风格
# 8、可以在函数内导入模块
def func():
import foo
-
执行
py文件
与导入py文件
的区别# 执行py文件时,产生对应py文件的名称空间,当该py文件的程序执行结束时名称空间才被回收 # 导入py文件时,py文件被当作模块引用,第一次导入模块时产生模块的名称空间,即导入的py文件的名称空间 # 当被导入py文件不再被其他文件所引用,即导入的py文件的引用计数为0时才会被回收 ''' 1、当foo.py被运行时,__name__的值为"__main__" 2、当foo.py被当作模块导入时,__name__的值为"foo" if __name__ == '__main__': print('文件被执行') else: print('文件被导入') ''' # import的优缺点 ''' import导入模块在使用时必须加前缀"模块." 优点:肯定不会与当前名称空间的名字冲突 缺点:加前缀显得麻烦 '''
2.2 from-import语句
# from...import...导入也发生了三件事
# 1、产生一个模块的名称空间
# 2、运行foo.py讲运行过程中产生的名字都丢到模块的名称空间
# 3、在当前名称空间拿到一个名字,该名字指向模块名称空间中的某一个内存地址
from foo import x # x=foo中1的内存地址
from foo import get
from foo import change
# x=33333
# print(x)
get()
change()
get()
print(x)
from foo import x # x=新的内存地址(0的内存地址)
print(x)
# from...import...导入模块在使用时不用加前缀
'''
优点:代码更精简
缺点:容易与当前名称空间混淆
from foo import x # x=foo中1的内存地址
x=1111
'''
# 一行导入多个名字(不推荐)
# from foo import x,get,change
# *: 导入模块中的所有名字(大多数情况下不推荐使用,极容易与当前名称空间的名字混淆)
# 当你需要用到同一个模块中的多个名字时,
# 此时可以使用*来进行代码精简,但也需要权衡,避免与当前名称空间的名字混淆
# 了解:__all__ 控制*代表的名字有哪些
from foo import *
print(x)
print(get)
print(change)
# 起别名
from foo import get as g
2.3 循环导入问题
# m1.py
print('正在导入m1')
# from m2 import y
def f1():
from m2 import y
print(y)
x='m1'
# m2.py
print('正在导入m2')
# from m1 import x
def f2():
from m1 import x
print(x)
y='m2'
# run.py
import m1
m1.f1()
2.4 搜索模块的路径与优先级
# 无论是import还是from...import在导入模块时都涉及到查找问题
# 优先级:
# 1、从内存找(内置模块)
# 2、按照sys.path中存放的文件的顺序依次查找要导入的模块
import sys
# 值为一个列表,存放了一系列的文件夹,
# 其中一个文件夹是当前执行文件所在的文件夹
print(sys.path)
# 了解:sys.modules查看已经加载到内存中的模块
# 针对模块的优化方案
import sys
import foo
def func():
import foo
func()
print(sys.modules)
# 找foo.py就把foo.py的文件夹临时添加到环境变量中
# 然后导入foo模块,程序结束append添加的环境变量就会被删除
sys.path.append(r'文件夹路径')
2.5 区分py文件的两种用途
#foo.py
...
if __name__ == '__main__':
print('文件被执行')
# oo.py被当做脚本执行时运行的代码
else:
print('文件被导入')
# foo.py被当做模块导入时运行的代码
2.6 编写一个规范的模块
-
该文件既是给自己用的,也有可能会被其他人使用,因而代码的可读性与易维护性显得十分重要,为此我们在编写一个模块时最好按照统一的规范去编写
"The module is used to..." #模块的文档描述 import sys #导入模块 x=1 #定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能 class Foo: #定义类,并写好类的注释 'Class Foo is used to...' pass def test(): #定义函数,并写好函数的注释 'Function test is used to…' pass if __name__ == '__main__': #主程序 test() #在被当做脚本执行时,执行此处的代码