python AI技术教程之模块

举报
tea_year 发表于 2025/11/21 16:44:35 2025/11/21
【摘要】 模块的概念在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。使用模块有什么好处?最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始...

模块的概念

在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)

使用模块有什么好处?

最大的好处是大大提高了代码的可维护性

其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块

使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。

你也许还想到,如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。

现在,假设我们的abcxyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:

mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py

引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz

请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany

类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:

mycompany
 ├─ web
 │  ├─ __init__.py
 │  ├─ utils.py
 │  └─ www.py
 ├─ __init__.py
 ├─ abc.py
 └─ utils.py

文件www.py的模块名就是mycompany.web.www,两个文件utils.py的模块名分别是mycompany.utilsmycompany.web.utils

特别注意

自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

mycompany.web也是一个模块,请指出该模块对应的.py文件。

小结

模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。


创建自己的模块时,要注意:

  • 模块名要遵循Python变量命名规范,不要使用中文、特殊字符;
  • 模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。

模块的使用

在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。

说的通俗点:模块就好比是工具箱,要想使用这个工具箱中的工具(就好比函数),就需要导入这个模块。

1.import

在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。

形如:

import os    => os.py
import time  => time.py

解释器遇到import语句,如果模块在当前的搜索路径就会被导入。

在调用math模块中的函数时,必须这样引用:

模块名.函数名

这种方式必须加上模块名调用,因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名。

在python中,模块通常可以分为两大类:内置模块(目前使用的)和自定义模块

2.模块的导入方式

import 模块名
import 模块名 as 别名

from 模块名 import *      # 代表导入这个模块所有的函数,可以直接通过函数名 调用函数
from 模块名 import 函数名  # 代表只导入这个函数名

3.as别名的使用

import random as rand # 将random取别名为rand
print(rand.randint(1,4))  # 通过别名来使用函数

4.time模块

"""
    time.time(): 获取当前时间,返回的是一个数字
    time.sleep(秒数): 休眠
"""
import time

star = time.time()  # 程序开始的时间
list = []
for i in range(100000):
    list.append(i)
end = time.time()  # 程序结束的时间

print(f'程序运行的时间为{star - end}s时间')

#定位模块

当你导入一个模块,Python解析器对模块位置的搜索顺序是:

1.当前目录

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

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

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

5.自定义模块

模块可以包含:全局变量、函数和类

# 创建一个自定义文件,如my_module1

def sum_num(num1, num2):
    return num1 + num2

在其他文件中导入自定义模块:

import my_module1

# 调用自定义模块中的函数
my_module1.sum_num(10, 20)

测试模块:

在编写完自定义模块后,最好在自定义模块中对代码进行测试,以免出现任何异常。

升级

__name__的使用

print(__name__)
if __name__ == '__main__':
    print('模块内部的测试')


调用者

import mycalc

print(mycalc.jia(2,38))

包的基础

2.1 什么是包?

包是一种包含多个模块的目录,它必须包含一个特殊的__init__.py文件(Python 3.3+中也可以是命名空间包,不需要__init__.py)。包可以嵌套,形成多层次的包结构。

2.2 包的结构

一个典型的包结构如下:

2.3 __init__.py文件的作用

__init__.py文件有以下作用:

1.标识目录为Python包

2.初始化包级别的代码

3.定义__all__变量,控制from package import *的行为

4.导入子模块或子包,使它们更容易访问

# bank_system/accounts/__init__.py

from .base import BankAccount
from .savings import SavingsAccount
from .checking import CheckingAccount

__all__ = ['BankAccount', 'SavingsAccount', 'CheckingAccount']

导入机制深入

3.1 模块搜索路径

当导入一个模块时,Python解释器按照以下顺序搜索:

1.内置模块(如sys、math等)

2.当前目录

3.环境变量PYTHON PATH指定的目录

4.标准库目录

5.第三方库目录(如site-packages)

可以通过sys.path查看搜索路径:

import sys
print(sys.path)

3.2 最佳实践

3.2.1 模块设计原则

  • 单一职责原则:每个模块应该只负责一个明确的功能
  • 高内聚低耦合:模块内部元素紧密相关,模块之间依赖最小化
  • 清晰的接口:模块应该提供清晰、稳定的API
  • 适当的抽象:隐藏实现细节,暴露必要的接口

3.2.2 包组织建议

  • 按功能而非类型组织代码
  • 保持包的扁平结构,避免过深的嵌套
  • 使用__init__.py简化导入
  • 为常用功能提供快捷方式

3.2.3 导入风格指南

  • 标准库导入
  • 第三方库导入
  • 本地应用/库导入
  • 每组导入之间空一行
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。