首页Python【Python基础】24....

【Python基础】24.模块和包


本系列文章配套代码获取有以下三种途径:

  • 可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):

https://returu.github.io/Python_Basic/lab/index.html
链接:https://pan.baidu.com/s/1x2Ynh_VibPY2u-HWTaJo8w?pwd=mnsj 提取码:mnsj
  • 前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Basic

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

Python的文件结构可以分为代码、模块和包。

1.模块和包:

1.1 模块:

当需要实现一个功能复杂的程序时,所需的代码量往往非常庞大,如果将所有代码都存放在一个文件中显然是不合适的,此时就需要将代码按照功能差费为若干文件,每个文件中存放实现特定功能的代码。

模块(Module)是包含任意Python代码的文件(Python文件后缀名为“.py”)。

养成使用模块的编程习惯,可以更加有效的组织自己的代码,提升代码的重用性和可维护性。

Python中的模块可以分为三种:

  • 内置模块:Python中自带的模块;

  • 第三方模块:需要单独下载安装的模块;

  • 自定义模块:根据需要自己编写的模块;

1.2 包:

当划分的模块很多时,后期维护起来也会很不方便,此时就需要使用到包(Package),包可以将多个模块(.py文件)存放在同一文件夹中,以便归类和管理。

包(Package)是存放模块文件的文件夹。

2.模块的导入方式:

模块的作用就是被导入到其他模块中,使得在被导入模块中可以使用导入模块的功能。

先编写一个简单的Python文件(create_lottery.py)作为模块,该模块中super_lotto()函数功能为随机生成一注大乐透,double_chromosphere()函数功能为随机生成一注双色球

 1import random
2
3def super_lotto():
4    red_ball = sorted(random.sample(range(1 , 36) , 5))
5    blue_ball = sorted(random.sample(range(1 , 13) , 2))
6
7    return f"本次大乐透结果——红球:{red_ball},蓝球:{blue_ball}。"
8
9def double_chromosphere():
10    red_ball = sorted(random.sample(range(1 , 34) , 6))
11    blue_ball = sorted(random.sample(range(1 , 17) , 1))
12
13    return f"本次双色球结果——红球:{red_ball},蓝球:{blue_ball}。"

2.1 直接导入:

使用import 模块文件名称语句可以将模块导入。
1# 直接导入模块
2>>> import create_lottery
3# 调用模块中大乐透生成函数
4>>> create_lottery.super_lotto()
5'本次双色球结果——红球:[2, 10, 13, 14, 20, 26],蓝球:[2]。'
6# 调用模块中双色球生成函数
7>>> create_lottery.double_chromosphere()
8'本次双色球结果——红球:[5, 6, 9, 17, 30, 32],蓝球:[2]。'

2.2 使用别名导入模块:

使用import 模块文件名称 as 模块别名语句可以使用别名导入模块

1# 使用别名导入模块
2>>> import create_lottery as cl
3# 调用模块中大乐透生成函数
4>>> cl.super_lotto()
5'本次大乐透结果——红球:[7, 13, 15, 20, 33],蓝球:[5, 7]。'
6# 调用模块中双色球生成函数
7>>> cl.double_chromosphere()
8'本次双色球结果——红球:[1, 9, 16, 19, 24, 31],蓝球:[6]。'

2.3 导入模块部分功能:

使用from 模块名称 import 函数(或变量)名称语句可以将模块内所需的函数或变量名称导入

1# 只导入模块中的super_lotto()函数
2>>> from create_lottery import super_lotto
3# 调用函数
4>>> super_lotto()
5'本次大乐透结果——红球:[1, 4, 11, 21, 25],蓝球:[5, 9]。'

2.4 导入模块全部功能:

使用from 模块文件名称 import *语句可以将模块汇总所有的函数(或变量)名称导入,除了以下划线开头的名称。

需要注意的是,使用该方式好处是比较方便 ,但是容易产生名称冲突(例如,需要导入的两个模块中有相同名称的函数),需要谨慎使用。

1# 导入模块全部功能
2>>> from create_lottery import *
3# 调用模块中大乐透生成函数
4>>> super_lotto()
5'本次大乐透结果——红球:[2, 8, 19, 24, 32],蓝球:[1, 4]。'
6# 调用模块中双色球生成函数
7>>> double_chromosphere()
8'本次双色球结果——红球:[2, 12, 13, 21, 24, 31],蓝球:[13]。'

2.5 导入包中的模块:

假设在当前目录下有一个creat_caipiao文件夹,里面包含create_super_lottocreate_double_chromosphere两个模块,文件目录结构如下图所示。

导入这些模块的方式为:

1# 导入模块并重命名
2>>> from create_caipiao import create_super_lotto as csl
3# 调用函数
4>>> csl.super_lotto()
5'本次大乐透结果——红球:[11, 27, 32, 34, 35],蓝球:[8, 12]。'

3.模块的搜索路径:

假定我们需要导入creat_caipiao文件夹下的create_super_lotto模块,我们直接使用下面的导入语句会报错,说是没有找到模块。
1>>> import create_super_lotto as csl
2ModuleNotFoundError: No module named 'create_super_lotto'

前面我们导入模块时,系统会尝试在一些目录中查看以寻找模块,查看系统查找的所有位置信息,需要使用内置sys模块中的path列表,列表包含目录名和ZIP归档文件,Python会依次在其中寻找需要导入的模块
 1# 查看模块的搜索路径
2>>> import sys
3>>> sys.path
4['E:\Python_Study\Python基础',
5 'D:\Anaconda\python39.zip',
6 'D:\Anaconda\DLLs',
7 'D:\Anaconda\lib',
8 'D:\Anaconda',
9 '',
10 'D:\Anaconda\lib\site-packages',
11 'D:\Anaconda\lib\site-packages\win32',
12 'D:\Anaconda\lib\site-packages\win32\lib',
13 'D:\Anaconda\lib\site-packages\Pythonwin']

可以在代码中对搜索路径进行相应修改,假设我们希望在搜索路径中加入一条E:Python_Study路径

 1# 添加一条路径
2>>> sys.path.append('E:Python_Study')
3>>> sys.path
4['E:\Python_Study\Python基础',
5 'D:\Anaconda\python39.zip',
6 'D:\Anaconda\DLLs',
7 'D:\Anaconda\lib',
8 'D:\Anaconda',
9 '',
10 'D:\Anaconda\lib\site-packages',
11 'D:\Anaconda\lib\site-packages\win32',
12 'D:\Anaconda\lib\site-packages\win32\lib',
13 'D:\Anaconda\lib\site-packages\Pythonwin',
14 'E:\Python_Study']

假设我们希望Python首先查找E:Python_StudyPython基础create_caipiao路径:

 1# 添加一条路径到第一位
2>>> sys.path.insert(0 , 'E:Python_StudyPython基础create_caipiao')
3>>> sys.path
4['E:\Python_Study\Python基础\create_caipiao',
5 'E:\Python_Study\Python基础',
6 'D:\Anaconda\python39.zip',
7 'D:\Anaconda\DLLs',
8 'D:\Anaconda\lib',
9 'D:\Anaconda',
10 '',
11 'D:\Anaconda\lib\site-packages',
12 'D:\Anaconda\lib\site-packages\win32',
13 'D:\Anaconda\lib\site-packages\win32\lib',
14 'D:\Anaconda\lib\site-packages\Pythonwin',
15 'E:\Python_Study']

此时我们在导入creat_caipiao文件夹下的create_super_lotto模块,可以看到不在报错。

1# 修改搜索路径后再导入模块
2>>> import create_super_lotto as csl
3# 调用函数
4>>> csl.super_lotto()
5'本次大乐透结果——红球:[7, 9, 23, 24, 28],蓝球:[4, 8]。'

4.模块属性:

模块除了被导入引用,还有对应的属性可供调用者查看。

属性
描述
__name__

模块名

当模块被导入其他模块时,名称为模块本身的名字;当该模块自己独立运行时,名称会变为__main__

__doc__ 模块详细说明
__package__ 所在包名
__loader__ 加载的类名
__spec__ 模块名字、加载类名、来源信息等概要内容
 1# 使用别名导入模块
2>>> import create_lottery as cl
3# 模块名称
4>>> cl.__name__
5'create_lottery'
6# 模块详细说明
7>>> cl.__doc__
8'n该模块中super_lotto()函数功能为随机生成一注大乐透,double_chromosphere()函数功能为随机生成一注双色球。n'
9# 所在包名,因为是单一模块,因此包名为空
10>>> cl.__package__
11''
12# 加载的类名
13>>> cl.__loader__
14<_frozen_importlib_external.SourceFileLoader at 0x16043499df0>
15# 模块的概要信息
16>>> cl.__spec__
17ModuleSpec(name='create_lottery', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000016043499DF0>, origin='E:\Python_Study\Python基础\create_lottery.py')

5.模块的常规写法:

编写模块时,可以将其自身作为独立运行的文件来为自身模块作单元测试,此时就需要接着模块名称属性的可变特性来实现。

例如,在模块最下面加入名称判断,并执行单元测试代码:

1if __name = '__main__':
2    <执行单元测试代码>

这样,当直接运行该模块文件时,可以通过测试代码来检验模块中定义的函数的输入输出是够正确。而在其他模块中引入该模块时,代码不会被执行。

因此为模块编写对应的单元测试代码时一个编程好习惯。

本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments