Python学习笔记(二十二)模块和包
一、模块
Python 模块(Module),是一个python 文件,以.py结尾,包含了Python对象定义和Python语句。模块能定义函数,类和变量,模块里也能包含可执行的代码。
1.1 导入模块
1.1.1 导入模块的方法
- import 模块名
- from 模块名 import 功能名
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
1.1.2 导入方式详解
# 需求: math 函数模块下的 sqrt() 开平方运算
'''
1. 导入模块
2. 测试是否导入成功,调用该模块内的sqrt 功能
'''
- 1.1.2.1 import
- 语法
# 1.导入模块
import 模块名
import 模块名1,模块名2...
# 2.调用功能
模块名.功能名()
- 体验
# 方法一: import 模块名; 模块名,功能
import math
print(math.sqrt(9)) # 3.0 除法运算都是返回浮点数‘’
- 1.1.2.2 from…import…
- 语法
from 模块名 import 功能1,功能2,功能3...
- 体验
# 方法二: from 模块名 import 功能1,功能2...
from math import sqrt
print(sqrt(9)) # 3.0 ,注意此时无需写模块名
- 1.1.2.3 from…import*
- 语法
from 模块名 import*
- 体验
# 方法三: from 模块名 import*
from math import *
print(sqrt(9)) # 3.0 ,注意此时也无需写模块名
- 1.1.2.4 as定义别名
- 语法
# 模块定义别名
import 模块名 as 别名
# 功能定义别名
from 模块名 import 功能 as 别名
- 体验
# 需求: 运行后暂停2s打印hello
'''
1. 导入time模块或者导入time模块的sleep功能
2. 调用功能
3. 打印hello
'''
# 模块别名
import time as tt
tt.sleep(2)
print('hello')
# 功能别名
from time import sleep as sl
sl(2)
print('hello')
1.2 制作模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说,自定义模块名要符合标识符命名规则。
问:那我们为什么要自定义模块呢?
答:自己定义的模块是封装自己项目中频繁使用的代码,模块使代码简化。
1.2.1 定义模块
新建一个Python文件,命名为my_module1.py
,并定义testA
函数。
def testA(a,b):
print(a+b)
# 测试模块功能
testA(1,1)
1.2.2 测试模块
那么在其他文件写代码的时候就可以导入这个模块的两个数加法功能,测试我们自定义的模块:
from my_module1 import testA
print(testA(3,4)) # 7
但是同时也把原来模块测试的代码结果2也给打印出来了,那么原来的模块代码如何修改呢,在不删除测试信息的基础上,使测试信息不出现在要调用这个模块信息的文件里面呢?
def testA(a,b):
print(a+b)
# 测试模块功能
# 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行testA函数调用
# ****__name__是系统变量,是模块的标识符,值是:如果是自身模块是__main__,否则是当前模块的名字。
if __name__ == '__main__':
testA(1,1)
此时,测试信息就不会出现在调用该模块的其他文件了。
1.3 模块的定位顺序
注意第一点的原因:因为Python解释器搜索模块时候,是由当前目录再到Python解释器目录下的文件,若当前目录下,有文件名与模块名重复,那么导入的是当前目录下的文件,是模块功能无法使用。
注意第二点的原因:当使用from xx import xx
功能 导入模块功能时候,如果功能名字重复,导入的时候,调用的是 后定义或后导入的这个同名功能。
from time import sleep
def sleep():
print("我是自定义的sleep")
sleep(2) # TypeError:sleep() takes 0 positional arguments but 1 was given
sleep() # 我是自定义的sleep
# 拓展 : 名字重复
# 问题 : 如果我们使用import 模块名 不需要担心功能名重复的问题
import time
print(time) # <module 'time' (built-in)> 内置模块time
time = 1
print(time) # 1, 变量名和模块名重复了,会覆盖模块
# 问题: 为什么变量也能覆盖模块? -- 在Python语言中,数据是通过 引用 传递的。
总结:尽量不要使名字重复,避免不必要的麻烦
1.4 __all__
如果一个模块文件有__all__
变量,当使用from xxx import*
导入时,只能导入这个列表中的元素。
- my_module1 模块代码
__all__ = ['testA']
def testA():
print('testA')
def testB():
print('testB')
- 导入模块的文件代码
from my_module import*
testA()
testB() # 语法报错
# 为什么testB()函数无法调用 -- 因为testB没有添加到all列表中,只有添加到all列表中才能被调用。
二、包
包将所有有联系的模块组织到一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py
,那么这个文件夹就成为包。
2.1 制作包
[New] – [Python Package] – 输入包名 – [OK] – 新建模块功能(有联系的模块)。
注意:新建包后,包内部会自动创建__init__.py
文件,这个文件控制着包的导入行为。
2.1.1 快速体验
1.新建包mypackage
2.新建包内模块:my_module1
和my_module2
3.模块代码如下
# my__module1
print(1)
def info_print1():
print("my_module1")
# my__module2
print(2)
def info_print2():
print("my_module2")
2.2 导入包
2.2.1 方法一
import 包名.模块名
包名.模块名.功能名()
# 方法一
'''
1. 导入
import 包名.模块名
2.调用功能
包名.模块名.功能()
'''
# 导入mypackage包下的模块1,使用这个模块里面的info_print1函数
import mypackage.my_module1
mypackage.my_module1.info_print1()
结果截图:
2.2.2 方法二
注意:必须在__init__.py
文件添加__all__ = [ ]
,控制允许导入的模块列表。
from 包名 import*
模块名,目标
# 方法二:注意__init__,py文件的all列表,添加的四允许导入的模块
'''
from 包名 import *
模块名.目标
'''
from mypackage import *
my_module1.info_print1()
结果截图: