Python编程:pkgutil获取包里面的所有模块列表

举报
彭世瑜 发表于 2021/08/13 23:57:15 2021/08/13
【摘要】 准备工作 环境: 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

参考

  1. Python 学习笔记 - 模块

文章来源: pengshiyu.blog.csdn.net,作者:彭世瑜,版权归原作者所有,如需转载,请联系作者。

原文链接:pengshiyu.blog.csdn.net/article/details/84062932

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。