第23节课 自定义模块与包
1 自定义模块
什么是模块
- 循环:重复执行的代码,且有规律
- 函数:将具有独立性功能的代码进行封装,以便后续复用/调用,解耦代码
- 模块:可以定函数、类和变量、也可以包含可执行的代码。可以把模块理解为更高级的函数-复用。一般而言我们会把一系列的功能封装到模块中,方便外界调用/复用。模块可以将程序代码进行组合和封装,提高代码的可维护性和可复用性。
- 表现:一个
.py
文件就是一个模块。
创建模块
# my_math.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
# 抛出异常
raise ValueError("除数不能为零")
return a / b
导入模块
(1)在另一个Python文件中,直接导入模块
import 模块名称
# main.py
import my_math
print(my_math.add(1,3))
print(my_math.subtract(3,1))
使用别名导入(就是给模块另起名字,一旦使用别名,本身的名称就不可用)
import 模块名称 as 别名
# main.py
import my_math as mm
print(mm.add(1,3))
print(mm.subtract(3,1))
(2)直接从模块中导入需要的对象(函数、变量、类)
from 模块 import 对象,对象...
# main.py
from my_math import add, subtract,multiply,divide
print(add(1,3))
print(subtract(4,1))
好处就是可以不用通过模块名称来去调用
坏处:
- 容易混淆,到底属于模块中的内容,还是当前定义的内容
- 少量代码编写时(简单的脚本文件),但是在大型项目中,不推荐的。
# main.py
from my_math import add, subtract,multiply,divide
def add(a,b):
return 666
print(add(1,3))
print(subtract(4,1))
(3)导入模块所有的对象
from 模块 import *
# main.py
from my_math import *
print(add(1,3))
print(subtract(4,1))
- 不推荐,理由同上
模块中__name__
的属性
- 每个Python模块都有一个内置属性
__name__
。当模块被直接运行时,__name__
的值为__main__
;当模块被导入时,__name__
的值为模块名称。 - 所谓的导入模块,就是先让模块的代码跑一遍,再去执行当前代码。
# my_math.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
# 抛出异常
raise ValueError("除数不能为零")
return a / b
# print(__name__)
# 当直接执行my_math.py文件时 则执行下面if中的内容
# 当my_math.py被导入时,则下面if中的内容不执行
if __name__ == "__main__":
print(f"测试:{add(1,1)}")
print(f"测试:{subtract(1,1)}")
2 自定义包
什么是包
包是一种管理Python模块的方式,它实际上就是一个包含多个模块的目录。包目录下必须有一个__init__.py
的文件,该文件就是用来标记当前目录是一个普通文件夹还是一个包。
在大型项目开发中,代码功能其实可以分为这么几类:model、view、controller、DB
创建包
创建一个名为my_package
的包,目录结构:
my_package
__init__.py
ModelC.py
ModelD.py
# ModelC.py
def show_modelC():
print("show_modelC run...")
# ModelD.py
def show_modelD():
print("show_modelD run...")
导入包中的模块
(1)相对导入
在包内,模块之间进行相互导入。【导包时,严禁相关导入,否则出现递归异常】
# ModelD.py
from . import ModelC
def show_modelD():
print("show_modelD run...")
ModelC.show_modelC()
(2)绝对导入
在包外,其他的模块中进行导入
# main.py
from my_package import ModelC, ModelD
ModelC.show_modelC()
ModelD.show_modelD()
__init__
的作用
- 标识一个目录是Python包
- 可以在其中定义包的初始化代码:导入包中的模块,使模块在包被导入时可用。
# __init__.py
from . import ModelC
from . import ModelD
# main.py
import my_package
my_package.ModelC.show_modelC()
my_package.ModelD.show_modelD()
__init__
中的__all__
变量
它是一个字符串列表,指定当前使用 from 包 import *
时应该导入的模块,做记录/指定导入。
# main.py
from my_package import *
ModelC.show_modelC()
ModelD.show_modelD()
print(dir())
# __init__.py
__all__ = ["ModelC", "ModelD"]