九、python模块以及python的包
9.1 python模块
定义:python模块(Module),是一个Python文件,以 .py 结尾. 模块能定义函数,类和变量,模块里也能包含可执行的代码。
语法:[from 模块名] import [模块 | 类 | 函数 | 变量 | *] [as 别名]
分类:内置模块和自定义模块。
说明:①模块的导入一般写在代码文件的开头位置。
②中括号在语法当中表示可选项的意思,所以关键字import必须写。星号表示导入模块内的所有内容。
常用的组合形式如:
①import 模块名
②from 模块名 import 类、变量、方法等
③from 模块名 import *
④import 模块名 as 别名
⑤from 模块名 import 功能名 as 别名
作用: python中有很多各种不同的模块,每一个模块都可以实现一些功能。比如实现和时间相关的功能就可以使用time模块。可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能。
9.1.1 python的内置模块
定义:python中丰富的第三方库内置的.py文件。
# 语法1
import 模块名
模块名.功能名() # 点表示层级关系
# 语法2:等价于语法1
from 模块名 import * # 使用模块内的所有方法、变量、类
功能名() # 直接输入功能名即可
举例:
import time # 导入python的内置时间模块,把光标放在time上,按住键盘CTRL+鼠标左击,直接跳转到time.py,因此时间模块的本质是time.py文件。
print("开始")
time.sleep(1) # 让程序睡眠1秒(阻塞):在time.py中搜索能找到sleep()函数,传入的参数是秒
print("结束")
# 等价于如下代码
from time import *
print("开始")
sleep(1)
print("结束")
并不是模块中所有的函数都会被使用。
# 语法
from 模块名 import 功能名
功能名()
举例:
from time import sleep # 导入时间模块中的sleep方法,不使用time.py的其他方法
print("开始")
sleep(1) # 直接输入功能名即可
print("结束")
有些模块名字很长,可以通过取别名的方式去调用对应的功能。
# 语法1:
import 模块名 as 别名 # 模块定义别名
# 语法2:
from 模块名 import 功能 as 别名 # 功能定义别名
举例:
# 模块定义别名
import time as t # t是time的别名
print("开始")
t.sleep(1)
print("结束")
# 功能定义别名
from time import sleep as ts # t是time的别名
print("开始")
ts(1)
print("结束")
9.1.2 python的自定义模块
定义:自己定义的模块,与内置模块是互斥的。
做法:自己新建一个Python文件,并定义1个函数实现某个功能。在另一个文件import自己写的python文件名,使用文件里面的函数即可。
注意:每个Python文件都可以作为一个模块,模块的名字就是文件的名字,也就是说自定义模块名必须要符合标识符命名规则。
# 导入不同模块的同名功能
from add import op, func # 写入代码 op(10, 20) 和 func("op") 后,发现这行代码变成灰色,跟注释一样
from sub import op, func # 调用到的是后面导入的模块的功能,即sub
# 除非仅仅使用import 模块名的语法,不然只能调用其中1个 op() 和 1个 func()
op(10, 20) # -10
func("op") # __name__ 在 sub.py 值为 op,数据类型为<class 'str'>
func(__name__) # __name__ 在 sub.py 值为 __main__,数据类型为<class 'str'>
# 新建1个 add.py,并定义函数
def op(a, b):
print(a + b)
def func(__name__):
print(f'__name__ 在 add.py 值为 {__name__},数据类型为{type(__name__)}')
注意事项:当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能。
举例:在上述代码的基础上,新增自定义模块。
# 新建1个 sub.py,并定义函数
def op(a, b):
print(a - b)
def func(__name__):
print(f'__name__ 在 sub.py 值为 {__name__},数据类型为{type(__name__)}')
在实际开发中,当编写完一个模块后,为了让模块能够在项目中达到想要的效果,开发人员会自行在自定义模块中添加一些测试信息,例如,在sub.py文件中添加测试代码test(100, 200),此时无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行test
函数的调用。
# 新建1个 sub.py,并定义函数
def op(a, b):
print(a - b)
def func(__name__):
print(f'__name__ 在 sub.py 值为 {__name__},数据类型为{type(__name__)}')
op(100, 200)
func("sub")
func(__name__)
问题:不希望在导入模块的文件右键点击run执行测试函数,但是又不想删除测试函数。
解决:python 有一个内置变量__name__,在 sub.py 模块中右键点击 run 运行,可以理解为把 sub.py 当前文件作为主函数,会将内置变量 name 标记为 main,此时 if 的值为 True, test(100, 200) 会被执行。但在 main.py 文件里右键点击 run 运行,把 main.py 当前文件作为主函数,内置变量 name 不会标记为 main,包含 name 变量的文件都不是主函数,if 的值为 False,test(100, 200) 不会被执行。
# 新建1个 sub.py,并定义函数
def op(a, b):
print(a - b)
def func(__name__):
print(f'__name__ 在 sub.py 值为 {__name__},数据类型为{type(__name__)}')
if __name__ == '__main__': # 在main.py文件里右键点击run运行如下代码,不会运行测试函数
op(100, 200) # -100
func("sub") # __name__ 在 sub.py 值为 sub,数据类型为<class 'str'>
func(__name__) # __name__ 在 sub.py 值为 main,数据类型为<class 'str'>
# if name == 'main': 的作用是判断当前模块是作为主程序运行,还是作为模块被其他程序导入并调用。
# 当模块被作为主程序直接运行时,__name__的值是'main',而当模块被导入时,__name__的值是模块名。
# 因此,在模块中加入if name == 'main':语句,可以让模块既可以直接运行,又可以被其他程序导入并调用,可以提高模块的复用性。
如果一个模块文件中有__all__
变量,当且仅当
使用from xxx import *导入时,只能导入这个列表中的元素。注意__all__
变量的值是一个列表。
# my_module.py
__all__ = ['test_a']
def test_a:
print('test_a')
def test_b:
print('test_b')
# main.py
from my_module import *
test_a() # right
test_b() # error,受到__all__变量的控制,不能使用test_b()
但是如果手动导入test_b函数,即使有__all__
变量控制,也不会报错,因为__all__
变量是控制星号。
# main.py
from my_module import test_b
test_b() # error,受到__all__变量的控制,不能使用test_b()
9.2 python包
9.2.1 自定义包
问题:在编写代码的时候,导入许多模块来丰富功能。但是如果Python的模块太多,就可能造成一定的混乱。
定义:从物理上看,包就是一个文件夹,在该文件夹下包含了一个 init.py 文件,该文件夹可用于包含多个模块文件。从逻辑上看,包的本质依然是模块。如果有文件夹有__init__.py 文件,这个文件夹就是python的包;如果没有,则就是一个普通的文件夹。
作用:当模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含多个模块,但包的本质依然是模块。
Pycharm中创建包步骤如下:在项目工程文件夹下鼠标右击New→Python Package。
输入包名。
按下Enter,出现__init__.py文件,发现面是空文件,但不用管__init__.py有无内容,只要有__init__.py即可。可以对比0924文件夹跟my_package文件夹,两者图标不一致。说明my_package是python包,0924只是普通文件夹。如果把__init__.py删除就会变成普通文件夹。
新建包内模块:my_module1
和 my_module2
,模块内代码如下:
# 导入包方式1:
import 包名.模块名
包名.模块名.目标
# 导入包方式2:
from 包名 import 模块名
模块名.函数名()
# 等价如下语法
from 包名.模块名 import 函数名
函数名()
举例:
from my_package import my_module1
from my_package import my_module2
my_module1.info_print1()
my_module2.info_print2()
# 等价如下代码
from my_package.my_module1 import info_print1
from my_package.my_module2 import info_print2
info_print1()
info_print2()
方式二:
注意:必须在__init__.py
文件中添加__all__ = []
,控制允许导入的模块列表。
my_module1报红证明不可用。
9.2.2 安装第三方包
定义:非Python官方包,Python没有内置,需要安装才可以导入使用的包。
作用:提高开发效率。
第三方包 | 作用 |
---|---|
numpy包 | 科学计算 |
pandas包 | 数据分析 |
pyspark、apache-flink包 | 大数据计算 |
matplotlib、pyecharts包 | 图形可视化 |
tensorflow包 | 人工智能 |
9.2.2.1 下载安装
9.2.2.1.1 命令行安装
命令行安装:使用Python内置的pip程序。
语法:在命令行输入pip install 包名
,即可通过网络快速安装第三方包。由于pip是连接的国外的网站进行包的下载,所以速度会很慢。也可以通过如下命令,让其连接国内的网站进行包的安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
,https://pypi.tuna.tsinghua.edu.cn/simple 是清华大学提供的一个镜像网站,可供pip程序下载第三方包。
以安装pyecharts包为例,输入pip install pyecharts
,等待联网下载并安装。
9.2.2.1.2 PyCharm安装
PyCharm也提供安装第三方包的功能(以numpy包为例)。
点击PyCharm右下角版本号,弹出对话框,点击Interpreter Settings。
在弹出的设置对话框,有列出当前已经安装第三方包,点击➕。
输入名称,点击Install Package。
因为Pycharm使用的也是国外网站下载的,如果觉得下载慢,可以在右下角处勾选Options,输入-i https://pypi.tuna.tsinghua.edu.cn/simple,再点击Install Package。按钮变灰,右下角出现进度条,等待安装完成,提示successful说明安装成功。
9.2.2.2 验证安装
9.2.2.2.1 命令行验证
安装完成后,输入python
进入python环境,接着输入import pyecharts
,回车,如果没有报错,说明pyecharts安装成功。
9.2.2.2.2 Pycharm验证
也可以在Pycharm输入import pyecharts.
,如果有相关选项,说明安装成功。
9.2.2.2.3 路径查询
安装所在路径,可以再次输入命令pip install 包名
即可。
9.3 案例:自定义工具包
创建一个自定义包,名称为:my_utils,在包内提供2个模块:
模块1:str_util.py (字符串相关工具,内含:)
–>函数1:str_reverse(s),接受传入字符串,将字符串反转返回;
–>函数2:substr(s, x, y),按照下标x和y,对字符串进行切片;
file_util.py(文件处理相关工具,内含:)
–>函数1:print_file_info(file_name),接收传入文件的路径,打印文件的全部内容,如文件不存在则捕获异常,输出提示信息,通过finally关闭文件对象;
–>函数2:append_to_file(file_name, data),接收文件路径以及传入数据,将数据追加写入到文件中。构建出包后,尝试着用一用自己编写的工具包。
# str_util.py
def str_reverse(s):
return s[::-1]
def substr(s, x, y):
return s[x:y]
if __name__ == '__main__':
my_str = "字符串相关工具"
print(str_reverse(my_str))
print(substr(my_str,1,3))
# file_util.py
def print_file_info(file_name):
f = None
try:
f = open(file_name,"r",encoding="UTF-8")
except:
print("文件不存在")
finally:
if f:
extent = f.read()
print(extent)
f.close()
def append_to_file(file_name, data):
f = open(file_name,"a",encoding="UTF-8")
f.write(data)
f.close()
if __name__ == '__main__':
print_file_info("D:/123.txt")
append_to_file("D:/123.txt","kljljjkhjjh")
# main.py
import my_utils.str_util
from my_utils import file_util
print(my_utils.str_util.str_reverse("接受传入字符串,将字符串反转返回"))
print(my_utils.str_util.substr("按照下标x和y,对字符串进行切片", 0, 4))
file_util.append_to_file("D:/test_append.txt", "将数据追加写入到文件中")
file_util.print_file_info("D:/test_append.txt")
码字不易,如果大家觉得有用,请高抬贵手给一个赞让文章上推荐让更多的人看到吧,也可以评论提出意见让后面的文章内容越来越生动丰富。