python学习 - 模块与包的基础概念
文章首发于我的个人博客:欢迎大佬们前来逛逛
@
模块
python提供了一种方法,可以使得在文件编写函数的定义,然后再另一个文件中可以导入这个文件中的函数的定义继而使用。这种文件就叫做模块。
模块可以导入另一个模块或者主模块中。
例如我们创建一个文件,内含两个函数,分别以不同的方式实现斐波那契数列:命名为 fibo.py
''' 斐波那契数列 ''' def fibo(n): a,b=0,1 while a<n: print(a,end=' ') a,b=b,a+b print() def get_fibo(n): l=[] a,b=0,1 while a<n: l.append(a) a,b=b,a+b return l
然后我们在另一个主文件或者其他文件中导入这个模块
import fibo
然后我们就可以使用fibo模块中的函数了,但是此时我们只是引入模块名 fibo
并没有引入函数名,可以通过模块名来访问函数:
- 通过
模块名+.
来访问 - 可以取一个别名,然后调用别名
# 通过模块访问模块中的函数 fibo.fibo(500) # 也可以改名 f = fibo.get_fibo l = f(500) print(l) ----------- 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
调用模块的不同方式
除了上面的 import 直接导入模块,我们还可以使用下面的方式来导入模块:
from fibo import fibo,get_fibo
:指定导入模块中的fibo和get_fibo的两个函数from fibo import *
:导入fibo中的所有函数。
作为脚本执行模块
在终端中作为脚本来执行此模块,这通常用于测试模块的功能。
只需要在终端中输入如下内容:
>>> python fibo.py <argument>
但是仅仅把我们的刚才的 [fibo.py](http://fibo.py)
文件作为测试是没有效果的,我们需要为 __name__
添加 __main__
属性:即在模块的后面加上如下的代码:
if __name__ == "__main__": import sys fibo(int(sys.argv[1]))
这样就可以这个模块像被导入一样来作为脚本执行,此代码只有在模块作为 main
文件执行时才被调用。
>> python fibo.py 50 0 1 1 2 3 5 8 13 21 34
包
包通常是使用用 圆点模块名
的结构化模块命名空间。名为 A.B
的模块表示了名为 A
的包中名为 B
的子模块。
使用包来防止模块之间出现名称相互冲突。
导入包的几种方式:
- 导入包的特定的模块
- 导入包中的子包
- 导入包中的模块的函数
例如我有一个模块,它的路径如下所示:
Include/test_floder/[fibo.py](http://fibo.py/)
其中我们的主文件与Include目录同级,那么我们该如何导导入 [fibo.py](http://fibo.py)
模块呢。
操作形式:from package import item
# ---- 方案一 ------ from Include.test_floder import fibo fibo.函数名 # ---- 方案二 ------ from Include from test_floder test_floder.子模块名.函数名 # ---- 方案三 ------ from Include.test_floder.fibo import get_fibo get_fibo() # 直接使用模块中的函数名
我们也可以直接使用 import
的方式来导入,但是要注意,使用此方法只能导入包或者模块,即上面的方案三无法通过这种方法导入模块内的名字
from Include.test_floder import fibo # 导入了fibo模块 fibo.函数名
从 * 导入包
我们的Include.test_floder
:中有很多的子模块。
如果我们执行了诸如: from Include.test_floder import *
会发生什么?
他会加载这个包中的所有的模块。
很明显这可能会花掉很长时间,并且出现期待之外的边界效应,导出了希望只能显式导入的包。
如果包的作者规定了一个 __init__.py
文件,并且给出了一个名为 __all__
的列表,那么按照列表中给出的模块名进行导入。
例如我们的 Include/test_floder
中是全部的子模块,其中有一个__init__.py
文件,内容如下:
__all__=["fibo", "test1", "test2", "test3"]
那么当我们使用 from Include.test_floder import *
的时候,就会导入该目录中的所有的定义的四个模块
如果我们把 __all__
的内容去掉,则我们在执行 from Include.test_floder import *
时,会发现:我们一个模块都没有导入!!! 因为我们的 * 只会导入 all
中定义的模块。
尽管某些模块设计为使用 import *
时它只导出符合某种规范/模式的命名,仍然不建议在生产代码中使用这种写法。
推荐使用 from Package import specific_submodule
这类写法。
本文来自博客园,作者:hugeYlh,转载请注明原文链接:https://www.cnblogs.com/helloylh/p/17333997.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)