Python编程:pkgutil获取包里面的所有模块列表
【摘要】 准备工作
环境: python 3.6
文件结构
├── clazz
│ ├── __init__.py
│ ├── a.py
│ └── b.py
└── main.py
12345
a.py 的代码
def show(): print("show A")
12
b.py 的代码
def show(): print("show B")
12 ...
准备工作
环境: python 3.6
文件结构
├── clazz
│ ├── __init__.py
│ ├── a.py
│ └── b.py
└── main.py
- 1
- 2
- 3
- 4
- 5
a.py
的代码
def show(): print("show A")
- 1
- 2
b.py
的代码
def show(): print("show B")
- 1
- 2
测试开始
1、获取模块中的属性
想要获取clazz
包中a
模块的所包含的方法,可以直接使用dir
这个函数,可以看到show
这个方法已经包含在其中
from clazz import a
print(dir(a))
"""
['__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__', 'show']
"""
"""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2、获取包中的属性
如果我要获取clazz
包中所有模块,直接使用dir
并没有获取
import clazz
print(dir(clazz))
"""
['__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__path__', '__spec__']
"""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
既然,模块可以查看其中包含的属性,而包其实就是一个文件夹
那么,先获取包文件夹下的所有模块文件,再逐个导入模块,最后也可以获取模块中的属性。
import os
import importlib
def get_modules(package="."): """ 获取包名下所有非__init__的模块名 """ modules = [] files = os.listdir(package) for file in files: if not file.startswith("__"): name, ext = os.path.splitext(file) modules.append("." + name) return modules
if __name__ == '__main__': package = "clazz" modules = get_modules(package) # 将包下的所有模块,逐个导入,并调用其中的函数 for module in modules: module = importlib.import_module(module, package) for attr in dir(module): if not attr.startswith("__"): func = getattr(module, attr) func() """ show A show B """
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
可以看到,我在只知道包名
的情况下,成功获取了包下所有模块,和模块中所有的方法,并成功调用
注意,相对导入的时候需要在模块名前面加.
but!!!,
Python推荐使用pkgutil.iter_modules(path=None, prefix='')
import pkgutil, clazz
for filefiner, name, ispkg in pkgutil.iter_modules(clazz.__path__, clazz.__name__ + "."): print("{0} name: {1:12}, is_sub_package: {2}".format(filefiner, name, ispkg))
"""
FileFinder('/Users/qmp/myproject/mydemo/demo/allclass/clazz') name: clazz.a , is_sub_package: False
FileFinder('/Users/qmp/myproject/mydemo/demo/allclass/clazz') name: clazz.b , is_sub_package: False
"""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
函数 iter_modules() 和 walk_packages() 的区别在于:后者会迭代所有深度的子包
import pkgutil, test
for _, name, ispkg in pkgutil.iter_modules(test.__path__, test.__name__ + "."):
print "name: {0:12}, is_sub_package: {1}".format(name, ispkg)
"""
name: test.a , is_sub_package: True
name: test.add , is_sub_package: False
name: test.b , is_sub_package: True
name: test.user , is_sub_package: False
"""
# 需要加第二个参数 prefix
for _, name, ispkg in pkgutil.walk_packages(test.__path__, test.__name__ + "."): print "name: {0:12}, is_sub_package: {1}".format(name, ispkg)
"""
name: test.a , is_sub_package: True
name: test.a.sub , is_sub_package: False
name: test.add , is_sub_package: False
name: test.b , is_sub_package: True
name: test.b.sub , is_sub_package: False
name: test.user , is_sub_package: False
"""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
pkgutil.get_data() 可读取包内任何文件内容
pkgutil.get_data("test", "add.py")
- 1
参考
文章来源: pengshiyu.blog.csdn.net,作者:彭世瑜,版权归原作者所有,如需转载,请联系作者。
原文链接:pengshiyu.blog.csdn.net/article/details/84062932
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)