1. 程式人生 > >Python程式設計:pkgutil獲取包裡面的所有模組列表

Python程式設計:pkgutil獲取包裡面的所有模組列表

準備工作

環境: python 3.6

檔案結構

├── clazz
│   ├── __init__.py
│   ├── a.py
│   └── b.py
└── main.py

a.py 的程式碼

def show():
    print("show A")

b.py 的程式碼

def show():
    print("show B")

測試開始

1、獲取模組中的屬性

想要獲取clazz包中a模組的所包含的方法,可以直接使用dir這個函式,可以看到show 這個方法已經包含在其中

from clazz import a

print
(dir(a)) """ ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'show'] """ """

2、獲取包中的屬性

如果我要獲取clazz 包中所有模組,直接使用dir 並沒有獲取


import clazz

print(dir(clazz))

"""
['__builtins__', '__cached__', '__doc__', '__file__', 
'__loader__', '__name__', '__package__', '__path__', '__spec__']
"""

既然,模組可以檢視其中包含的屬性,而包其實就是一個資料夾
那麼,先獲取包資料夾下的所有模組檔案,再逐個匯入模組,最後也可以獲取模組中的屬性。


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 """

可以看到,我在只知道包名的情況下,成功獲取了包下所有模組,和模組中所有的方法,併成功呼叫

注意,相對匯入的時候需要在模組名前面加.

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. Python 學習筆記 - 模組