Python语言实践分析 -- 包导入

本文深入分析了Python中的包导入机制,包括直接导入包、导入模块、使用`import *`、利用`__all__`控制以及`__init__.py`的控制方式。详细探讨了不同导入方法对包和模块执行的影响,以及如何通过`__init__.py`进行导入控制。
摘要由CSDN通过智能技术生成

Python语言实践分析 – 包导入

标签(空格分隔): Python


Python中的包

与JAVA语言一样,Python中也有包的概念。Python中的包就是一个包含Python模块(就是python文件)的目录,作为与普通目录的区别,Python的包目录必须包含一个__init__.py的文件。包允许嵌套。
对于导入一个包有多种方法,我们依次来分析一下各种方法的差别。

#1 直接导入包
import testpkg
#2 导入包里面的具体模块
import testpkg.modulea
from testpkg import modulea
#3 使用*导入一个包
from testpkg import *

实践

我们的包结构设计如下:

路径
test.py
testpkg__init__.py
modulea.py
moduleb.py

先在每个文件中添加如下代码,用于查看不同导入执行的文件

print('excute file', __file__)

而测试的主执行文件,test.py中则输入如下代码:

import sys
base_modules = set(sys.modules.keys())
local_names = set(dir())

# 测试代码修改
import testpkg

now_modules = set(sys.modules.keys())
now_names = set(dir())
print('模块名增加', now_modules - base_modules)
print('变量名增加', now_names - local_names - set(['now_modules', 'local_names']))

1 直接导入包

测试代码如上所示,其执行结果如下:

excute file /home/spirit/文档/pkg/testpkg/__init__.py
模块名增加 {'testpkg'}
变量名增加 {'testpkg'}

可以看到执行import包实际上是执行了其中的__init__.py,而其中的模块文件是没有执行,执行调用模块,则会产生异常(testpkg.modulea)。

2 导入模块

  • import testpkg.modulea
    将测试代码修改后,结果如下,可以看到执行了包的__init__.py文件以及具体的模块文件,而且两者都生成了新的模块。
excute file /home/spirit/文档/pkg/testpkg/__init__.py
excute file /home/spirit/文档/pkg/testpkg/modulea.py
模块名增加 {'testpkg.modulea', 'testpkg'}
变量名增加 {'testpkg'}
  • from testpkg import modulea
    代码修改后,结果如下,可以看到执行结果唯一与上面不一致的是引入的本地变量名不一样。
excute file /home/spirit/文档/pkg/testpkg/__init__.py
excute file /home/spirit/文档/pkg/testpkg/modulea.py
模块名增加 {'testpkg.modulea', 'testpkg'}
变量名增加 {'modulea'}

3 import * 导入

代码修改后,可以看到其执行结果,可以看到其实际上只执行了初始化文件。

excute file /home/spirit/文档/pkg/testpkg/__init__.py
模块名增加 {'testpkg'}
变量名增加 set()

4 __all__控制

Python还支持在__init__.py文件中用一个__all__导入进行控制,在__init__.py中代码中添加如下代码:

__all__ = ['modulea', 'moduleb']

可以发现执行 import*导入时的结果与之前不一样,如下:

excute file /home/spirit/文档/pkg/testpkg/__init__.py
excute file /home/spirit/文档/pkg/testpkg/modulea.py
excute file /home/spirit/文档/pkg/testpkg/moduleb.py
模块名增加 {'testpkg', 'testpkg.moduleb', 'testpkg.modulea'}
变量名增加 {'modulea', 'moduleb'}

而其他导入方法均没有变化。

5 __init__.py控制

在我们平常的操作中,往往希望如下代码是可以运行的,这时就可以通过修改__init__.py,在里面加入相应的执行代码,直接import对应的模块或者递归import子包。需求不一样,实现控制的方式也多种多样。

import A
A.B.C.d()

总结

  • 对于import A.B.C.D 方式来导入包时,其依次执行导入包路径上的包(A、B、C)的__init__.py,如果最后(D)是模块,则导入模块,否则其为嵌套包也是执行文件夹下的__init__.py。
  • 对于from A.B import C.D这种格式导入时,其与上面的效果一致,不同是本地名不一样,前面一种格式产生的变量名为A,而这里产生变量名C。
  • from A.B.C import *导入时,会依次执行路径上包(A、B、C)的__init__.py,在执行完C的__init__.py后,会寻找C.__all__变量,将其中的模块导入。
  • 对于包使用的不同需求,可以通过包里面的__init__.py添加导入语句对访问进行控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值