什么是模块?
模块是包含 Python 定义和语句的文件,其文件名是模块名加后缀名 .py ,简而言之,在Python中,一个.py文件就是一个模块。在模块内部,通过全局变量 __name__ 可以获取模块名(即字符串)。
为什么需要模块?
在不引入模块的情况下,编写一个功能简单的程序,代码行数在千行以内时,看起来好像也不是什么大的问题;然而当我们在编写一个非常大的程序时,程序代码量可能上万行甚至更多,在如此大的一个文件中进行功能的完善和维护,可以想象是如何的困难。
基于此,Python引入了模块,可以将功能逻辑上相同的代码放在一个独立的文件中。这样,每个独立文件可以表示一部分功能,在进行功能的维护时,只需要修改这一个独立文件即可,不需要大海捞针。
我们使用独立的文件定义好模块,接下来就需要在上层引入模块,执行模块内部定义的逻辑。
语法:
import 模块名import 模块名 as 别名from 模块名 import 函数或其他from 模块名 import *as是用来声明导入模块的别名,一个情况是可以将模块进行重命名,另一个方面是:如果在当前模块中导入了两个不同的模块,而这两个模块名称可能相同,为了避免命名冲突,使用as进行重命名*会导入所有不以下划线(_)开头的名称。大多数情况下,不要用这个功能,这种方式向解释器导入了一批未知的名称,可能会覆盖已经定义的名称。示例:

定义 mymath.py模块
# adddefadd(a, b):return a + b# subtractdefsubtract(a, b):return a - b# multiplydefmultiply(a, b):return a * b# dividedefdivide(a, b):if b == 0:raise ValueError("Cannot divide by zero.")return a / b1、在 test.py中使用mymath模块
import mymathprint("Addition of 5 and 3:", mymath.add(5, 3))print("Subtraction of 5 and 3:", mymath.subtract(5, 3))print("Multiplication of 5 and 3:", mymath.multiply(5, 3))print("Division of 5 and 3:", mymath.divide(5, 3))# 输出Addition of 5and3: 8Subtraction of 5and3: 2Multiplication of 5and3: 15Division of 5and3: 1.66666666666666672、使用别名:
import mymath as myprint("Addition of 5 and 3:", my.add(5, 3))print("Subtraction of 5 and 3:", my.subtract(5, 3))print("Multiplication of 5 and 3:", my.multiply(5, 3))print("Division of 5 and 3:", my.divide(5, 3))3、导入具体的函数:
from mymath import add, divideprint("Addition of 5 and 3:", add(5, 3))print("Subtraction of 5 and 3:", subtract(5, 3))print("Multiplication of 5 and 3:",multiply(5, 3))print("Division of 5 and 3:", divide(5, 3))由于已经使用import直接导入了模块内部具体的函数,所以在调用的时候,就不需要在函数名前增加模块名。
另外由于我们只导入了add和divide函数,所以在执行substract时会报错:NameError: name 'subtract' is not defined
4、使用*导入全部
from mymath import *print("Addition of 5 and 3:", add(5, 3))print("Subtraction of 5 and 3:", subtract(5, 3))print("Multiplication of 5 and 3:",multiply(5, 3))print("Division of 5 and 3:", divide(5, 3))*会把mymath模块下所有不以_开头的内容都导入,函数调用前不需要在添加模块名
包是在模块的基础上,将模块在按照逻辑分类,在导入模块的时候,包名称也作为导入路径的一部分。定义包的时候,需要在包目录下新建一个__init__.py文件,文件内容可以为空。
假设要为统一处理声音文件与声音数据设计一个模块集(“包”)。声音文件的格式很多(通常以扩展名来识别,例如:.wav,.aiff,.au),因此,为了不同文件格式之间的转换,需要创建和维护一个不断增长的模块集合。为了实现对声音数据的不同处理(例如,混声、添加回声、均衡器功能、创造人工立体声效果),还要编写无穷无尽的模块流。下面这个分级文件树展示了这个包的架构:
sound/ 最高层级的包 __init__.py 初始化 sound 包 song.py formats/ 用于文件格式转换的子包 __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... effects/ 用于音效的子包 __init__.py echo.py surround.py reverse.py ... filters/ 用于过滤器的子包 __init__.py equalizer.py vocoder.py karaoke.py ...语法:
import 父.子.模块from 父.子 import 模块1,模块2from 父.子 import *# 相对导入from . import 模块名 # 使用当前模块所在路径查找 导入模块from .. import 模块名 # 使用当前模块的直接父模块from ..同级包名 import 模块名 #引入同级包下的模块* 的使用需要在包的__init__.py文件中通过__all__ 声明需要导出的模块python运行文件的时候,如果模块A使用相对路径引入了其他模块,不能直接运行python a.py,否则会报错:ImportError: attempted relative import with no known parent package举例:

1、直接导入模块:
使用 import直接导入全路径模块时,在使用的时候也需要完整的模块路径,较为繁琐
import sound.effects.echoprint(sound.effects.echo.echo_str("Hello"))2、使用from 包路径 import 模块方式:
使用此种方式,在使用的时候可以直接使用最后的模块名,不需要前边的包路径,推荐采用
from sound.effects import echoprint(echo.echo_str("Hello")) # Expected output: "Hello Hello"3、使用from 包路径 import *方式:
# 在 sound.effercts.__init__py文件中添加 __all__ 声明导出 errercts包下的 echo 模块__all__ = ['echo']from sound.effects import *print(echo.echo_str("Hello"))print(reverse.reverse_str("Hello"))# 由于没有在 __all__ 中声明导出 reverse,所以在执行 reverse.reverse_str时会报错Hello HelloTraceback (most recent call last): File "/test.py", line 4, in <module> print(reverse.reverse_str("Hello")) ^^^^^^^NameError: name 'reverse'isnot defined. Did you mean: 'reversed'?4、使用相对路径 .:
在 reverse.py文件中通过相对路径引入 echo模块
from . import echodefreverse_str(s):"""Reverses the given string s."""return s[::-1]defcall_echo(): echo.echo_str("Test")顶层 test.py中调用 reverse模块的call_echo函数
from sound.effects import reversereverse.call_echo()# 输出Echoing string: Test注意实现: 如果在effects目录下直接使用python reverse.py调用echo模块的函数,会发生错误:ImportError: attempted relative import with no known parent package
5、使用相对路径 ..
在wavread.py 文件中通过相对引用,引入父包sound下的song模块
from .. import songdefread_wav(filename): print(f"Reading WAV file: {filename}")defsing_a_song(): song.sing()顶层test.py中引入wavread模块
from sound.formats import wavreadwavread.sing_a_song()# 输出La la la...6、使用相对路径引入同级包下的模块 ..同级包名
在wavread.py 文件中通过相对引用,引入当前模块所属包 formats的同级包effects下的echo模块
from ..effects import echodefread_wav(filename): print(f"Reading WAV file: {filename}")defcall_echo(): echo.echo_str("Calling from wavread")顶层test.py中引入wavread模块
from sound.formats import wavreadwavread.call_echo()# 输出Echoing string: Calling from wavread