day18 课程(模块 & 导入模块 & 制作模块 & 模块定位顺序 & all列表 & 包 & 制作包 & 导入包)

课程:https://www.bilibili.com/video/BV1o4411M71o?spm_id_from=333.788.videopod.episodes&p=333

18.1 了解模块

18.1.1 目标

  了解模块

  导入模块

  制作模块

  __all__

  包的使用方法

18.1.2 模块

  Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和 Python 语句

模块能定义函数、类和变量,模块里也能包含可执行的代码

18.2 导入模块之方法一

18.2.1 语法

# 1.导入模块
import 模块名  # 推荐
import 模块名1, 模块名2, ... # 不推荐

# 2.调用功能
模块名.功能名()

18.2.2 体验

# 1 导入模块
import math

# 2 调用模块内的功能
print(math.sqrt(9))  # sqrt 开平方, 相除无论是整数还是浮点数, 最后都得浮点数 3.0

print(6 / 2)  # 举例: 两个整数最后得浮点数 3.0

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day18\01.模块的使用方法.py 
3.0
3.0

Process finished with exit code 0

18.3 导入模块之方法二

18.3.1 语法

from 模块名 import 功能1, 功能2, 功能3, ...

18.3.2 体验

# 1 导入模块中的功能名字
from math import sqrt

# 2 调用模块内的功能
print(sqrt(100))  # 不用写模块名, 直接调用功能即可

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day18\01.模块的使用方法.py 
10.0

Process finished with exit code 0

18.4 导入模块之方法三

18.4.1 语法

from 模块名 import *

18.4.2 体验

# 1 导入模块中的所有功能
from math import *

# 2 调用模块内的功能
print(sqrt(100))  # 不用写模块名, 直接调用功能即可

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day18\01.模块的使用方法.py 
10.0

Process finished with exit code 0

18.5 定义别名

18.5.1 语法

注意:定义别名以后,只能使用别名,不能使用原模块名或功能名

# 模块定义别名
import 模块名 as 别名

# 功能定义别名
from 模块名 import 功能 as 别名

18.5.2 体验

# 1 模块别名
import time as te

te.sleep(3)
print("hello world")

# 2 功能别名
from time import sleep as sp

sp(3)
print("hello python")

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\02.定义别名.py 
hello world
hello python

Process finished with exit code 0

18.6 了解制作模块

在 Python 中,每个 Python文件都可以作为一个模块,模块的名字就是文件的名字,也就是说 自定义模块名必须要符合标识符命名规则

用作:简化代码量,可以拿来即用

18.7 制作模块之定义模块

新建一个 Python 文件,命名为 my_module.py ,并定义 test 函数

# 定义函数、形参、返回值
def test(A, B):
    print(A + B)

18.8 制作模块之测试和调用模块

18.8.1 测试模块

在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,开发人员会自行在 py文件中添加一些测试信息,例如:在 my_module1.py 文件中添加测试代码

# 定义函数、形参、返回值
def testA(A, B):
    print(A + B)

# 先在本模块中测试, 其他文件调用此模块时, 导入所有代码会把测试代码也调用一遍, 影响结果
testA(1, 2)  # 测试后这个测试内容怎么办?

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\my_module.py 
3

Process finished with exit code 0

18.8.2 调用模块

# 调用模块
import my_module

# 调用模块中的功能
my_module.testA(1,6)  # 返回 7

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\03.调用制作的模块.py 
3  # 这里 3 是测试时的调用,影响其他模块的调用结果
7

Process finished with exit code 0

注意:返回 3 是 my_module 原文件整个被调用到其他文件中,影响调用文件的输出结果

18.8.3 测试模块仅本地调用

注意:,在开发过程中,文件被频繁的修改,测试,删除和注释也会浪费大量时间,如何解决?

此时,无论是当前文件还是其他已经导入该模块的文件,在运行的时候都会自动执行 test函数 的调用

# 定义函数、形参、返回值
def testA(A, B):
    print(A + B)

# 先在本模块中测试, 其他文件调用此模块时, 导入所有代码会把测试代码也调用一遍, 影响结果
# testA(1, 2)  # 测试后这个测试内容怎么办?

print(__name__)   # __name__ 是模块内置的变量, 如果运行的本模块, 则为 __main__ ,其他模块调用则会打印此模块名称

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\my_module.py 
__main__  # 本模块自己调用返回 __main__

Process finished with exit code 0
# 调用模块
import my_module

# 调用模块中的功能
my_module.testA(1,6)  # 返回 7

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\03.调用制作的模块.py 
my_module  # 其他模块调用返回原模块名称
7

Process finished with exit code 0

由此,解决办法如下:

# 定义函数、形参、返回值
def testA(A, B):
    print(A + B)

# 先在本模块中测试, 其他文件调用此模块时, 导入所有代码会把测试代码也调用一遍, 影响结果
# testA(1, 2)  # 测试后这个测试内容怎么办?

# 只在当前文件中调用该函数, 其他导入的文件内不符合该条件, 则不执行 test函数 调用
if __name__ == '__main__':  # __name__ 是模块内置的变量, 如果运行的此模块, 则为 __main__ ,其他模块调用则会打印此模块名称
    testA(1,2)  # 本模块自己测试时使用, 不会影响其他模块调用输出的结果

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\my_module.py 
3

Process finished with exit code 0

其他文件调用此模块

# 调用模块
import my_module

# 调用模块中的功能
my_module.testA(1,6)  # 返回 7, 测试的函数不会执行, 不会干扰模块调用

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\03.调用制作的模块.py 
7

Process finished with exit code 0

18.9 了解模块定位顺序

当导入一个模块,Python 解释器对模块位置的搜索顺序是:由近及远

  1.当前目录

  2.如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 的每个目录

  3.如果都找不到,Python 会查看默认路径,例如:UNIX 下,默认路径一般为 /usr/local/lib/python/

模块搜索路径存储在 sys模块 的 sys.path 变量中,变量里包含当前目录,PYTHONPATH 和由安装过程决定的默认目录

import sys
print(sys.path)

注意点:

  1.自己的文件名不要和已有模块名重复,否则导致模块功能无法使用

  2.使用 from 模块名 import 功能 的时候,如果功能名字重复,调用到的是最后定义或导入的功能

18.10 模块定位顺序之注意点1

默认情况下:

import random

num = random.randint(1, 5)
print(num)  # 出现 1-5 的随机数

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\05.模块定位顺序之注意点1.py 
4

Process finished with exit code 0

当在同一目录下创建一个 random 的文件,里面是空内容,模块名重复,导致模块无法使用

import sys
# 强制从缓存中移除 random 模块
if 'random' in sys.modules:
    del sys.modules['random']

import random

num = random.randint(1, 5)  # 因为有同名 random 模块, randint有黄色下划线, 警告没有 randint 方法
print(num)  # 上面报错,导入了同一目录下 random模块,没有 randint 方法

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\05.模块定位顺序之注意点1.py 
Traceback (most recent call last):
  File "D:\Pycharm\code\day18\05.模块定位顺序之注意点1.py", line 11, in <module>
    num = random.randint(1, 5)  # 因为有同名 random 模块, randint有黄色下划线, 警告没有
AttributeError: module 'random' has no attribute 'randint'

Process finished with exit code 1

18.11 模块定位顺序之注意点2

默认情况下:

from time import sleep

print("A")
sleep(2)  # 休眠了2秒后, 输出下面内容
print("B")

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\06.模块定位顺序之注意点2.py 
A
B

Process finished with exit code 0

当在同一文件中导入相同名字的功能,功能名字重复,后导入的生效

from time import sleep

def sleep():
    print('自定义sleep函数')

print("A")
sleep(2)  # 报错: 函数未定义参数 TypeError: sleep() takes 0 positional arguments but 1 was given 说明使用的是 自己定义的sleep 函数
print("B")

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\06.模块定位顺序之注意点2.py 
Traceback (most recent call last):
  File "D:\Pycharm\code\day18\06.模块定位顺序之注意点2.py", line 9, in <module>
    sleep(2)  # 休眠了2秒后, 输出下面内容
TypeError: sleep() takes 0 positional arguments but 1 was given
A

Process finished with exit code 1

相同的代码,当顺序发生变化

def sleep():
    print('自定义sleep函数')

from time import sleep

print("A")
sleep(2)  # 休眠了2秒后, 输出下面内容 说明使用的是 time 模块中的 sleep 功能
print("B")

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\06.模块定位顺序之注意点2.py 
A
B

Process finished with exit code 0

18.12 扩展:名字重复的严重性

注意:import 模块名 多个后,即使功能名相同,但使用方式是 模块名.功能名 ,模块名不同,所以也不用担心功能重复

import time  # 导入模块

print(time)  # 打印模块 module time

time = 1  # 声明变量
print(time)  # 返回 1 当声明变量与导入模块名相同, 后导入的生效, 覆盖前面

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\07.扩展:名字重复的严重性.py 
<module 'time' (built-in)>
1

Process finished with exit code 0

问题:为什么变量也能覆盖模块?

答:在 Python 中,数据是通过 引用 传递的,因此要注意名字重复的严重性

18.13 __all__ 列表

如果一个模块文件中有 __all__ 变量,当使用 from xxx import * 导入时,只能导入这个列表中的元素

my_module1 模块代码

__all__ = ['testA']  # 列表中只放了 testA

def testA():  # testA 函数
    print('testA')

def testB():  # testB 函数
    print('testB')

导入模块的文件代码

from my_module1 import *

testA()  # 返回 testA

testB()  # 报错 NameError 因为 my_module1模块, 控制了只有 all列表 里面的功能才能导入

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe "D:\Pycharm\code\day18\08.__all__ 列表.py" 
testA
Traceback (most recent call last):
  File "D:\Pycharm\code\day18\08.__all__ 列表.py", line 6, in <module>
    testB()
NameError: name 'testB' is not defined

Process finished with exit code 1

18.14 了解包

包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为 __init__.py 文件,这个文件称为包(即一个文件夹下多个模块的整合,只要找到这个包,即能使用包下所有模块的功能)

18.15 制作包

[New] -> [Python Package] -> 输入包名 -> [OK] -> 新建功能模块(有联系的模块)

注意:新建包后,包内部会自动创建 __init__.py 文件,这个文件控制着包的导入行为

18.15.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')

18.16 导入包之方法一

18.16.1 导入1

import 包名.模块名  # 导入

包名.模块名.功能名  # 使用

18.16.2 体验

import mypakcage.my_module1  # 导入 包名 模块名

mypakcage.my_module1.info_print1()  # 使用 包名 模块名 功能名

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\09.导入包之方法一.py 
1
my_module1

Process finished with exit code 0

18.17 导入包之方法二

注意:必须在 __init__.py 文件中添加 __all__ = [] ,控制允许导入的模块列表

18.17.1 导入2

from 包名 import *  # 导入

模块名.功能名  # 使用

18.17.2 体验

# __init__.py 文件
__all__ = ['my_module2']
from mypakcage import *  # 导入 包名

my_module2.info_print2()  # 可以使用 使用 模块名 功能名
my_module1.info_print1()  # 无法使用 没在 __init__.py 文件中 __all__列表 定义, 无法使用 报错:NameError

------------------------------------------------ 执行后
C:\Users\马俊南\AppData\Local\Programs\Python\Python37\python.exe D:\Pycharm\code\day18\10.导入包之方法二.py 
Traceback (most recent call last):
  File "D:\Pycharm\code\day18\10.导入包之方法二.py", line 5, in <module>
    my_module1.info_print1()
NameError: name 'my_module1' is not defined
2
my_module2

Process finished with exit code 1

18.18 模块和包的总结

1.导入模块方法

import 模块名

from 模块名 import 功能

from 模块名 import *

注意:as 别名 对模块或功能重命名,调用时使用别名

2.创建包

[New] -> [Python Package] -> 输入包名 -> [OK] -> 新建功能模块(有联系的模块)

3.导入包

import 包名.模块名

from 包名 impoort *  # __init__.py 文件中需要定义 __all__ =[]

注意:__all__ = [] :允许导入的模块或功能列表

———————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2025-10-06 17:43  马俊南  阅读(9)  评论(0)    收藏  举报