编程学习
🐍Python(3)模块与包的概念
00 分钟
2023-4-20
2023-11-23
type
status
date
slug
summary
tags
category
icon
password
Email

模块

python提供了一种方法,可以使得在文件编写函数的定义,然后再另一个文件中可以导入这个文件中的函数的定义继而使用。这种文件就叫做模块
模块可以导入另一个模块或者主模块中。
例如我们创建一个文件,内含两个函数,分别以不同的方式实现斐波那契数列:命名为 fibo.py
然后我们在另一个主文件或者其他文件中导入这个模块
然后我们就可以使用fibo模块中的函数了,但是此时我们只是引入模块名 fibo 并没有引入函数名,可以通过模块名来访问函数:
  1. 通过 模块名+. 来访问
  1. 可以取一个别名,然后调用别名

调用模块的不同方式
除了上面的 import 直接导入模块,我们还可以使用下面的方式来导入模块:
  • from fibo import fibo,get_fibo:指定导入模块中的fibo和get_fibo的两个函数
  • from fibo import * :导入fibo中的所有函数。

作为脚本执行模块

在终端中作为脚本来执行此模块,这通常用于测试模块的功能。
只需要在终端中输入如下内容:
但是仅仅把我们的刚才的 fibo.py 文件作为测试是没有效果的,我们需要为 __name__ 添加 __main__ 属性:即在模块的后面加上如下的代码:
这样就可以这个模块像被导入一样来作为脚本执行,此代码只有在模块作为 main 文件执行时才被调用。

包通常是使用用 圆点模块名 的结构化模块命名空间。名为 A.B的模块表示了名为 A的包中名为 B 的子模块。
使用包来防止模块之间出现名称相互冲突。
导入包的几种方式:
  1. 导入包的特定的模块
  1. 导入包中的子包
  1. 导入包中的模块的函数
例如我有一个模块,它的路径如下所示:
Include/test_floder/fibo.py
其中我们的主文件与Include目录同级,那么我们该如何导导入 fibo.py 模块呢。
操作形式:from package import item
我们也可以直接使用 import 的方式来导入,但是要注意,使用此方法只能导入包或者模块,即上面的方案三无法通过这种方法导入模块内的名字

从 * 导入包

我们的Include.test_floder:中有很多的子模块。
如果我们执行了诸如: from Include.test_floder import * 会发生什么?
他会加载这个包中的所有的模块。
很明显这可能会花掉很长时间,并且出现期待之外的边界效应,导出了希望只能显式导入的包。
如果包的作者规定了一个 __init__.py 文件,并且给出了一个名为 __all__ 的列表,那么按照列表中给出的模块名进行导入。
例如我们的 Include/test_floder 中是全部的子模块,其中有一个__init__.py 文件,内容如下:
那么当我们使用 from Include.test_floder import * 的时候,就会导入该目录中的所有的定义的四个模块
如果我们把 __all__ 的内容去掉,则我们在执行 from Include.test_floder import * 时,会发现:我们一个模块都没有导入!!! 因为我们的 * 只会导入 all 中定义的模块。
尽管某些模块设计为使用 import *时它只导出符合某种规范/模式的命名,仍然不建议在生产代码中使用这种写法。
推荐使用 from Package import specific_submodule 这类写法。

 

评论
  • Twikoo
  • Valine