Source code for commonutil.moduleimp
# -*- coding: utf-8 -*-
""" 模組載入支援函式 / Module load routines """
import sys
import imp
from pkgutil import iter_modules
from itertools import chain as iter_chain
[docs]def get_module_file_suffixes():
# type: () -> frozenset
"""
取得模組檔案的延伸檔名
Get the file name extension of modules
Return:
存有模組檔案延伸檔名的集合物件 / Set object keeps file name extension of modules
"""
return frozenset(map(lambda x: x[0], imp.get_suffixes()))
[docs]def get_module(module_ident):
# type: (str) -> Any
"""
取得給定的模組識別字串所指向的模組或套件物件
Get the module object (or package object) identify by given module identifier
Args:
module_ident: 模組識別字串 / Module identifier (ex: "commonutil.moduleimp")
Return:
所載入的模組物件 / Loaded module object
"""
try:
return sys.modules[module_ident]
except KeyError:
pass
aux = module_ident.split(".")
mod_name = aux[-1]
if len(aux) == 1:
fp, pathname, description, = imp.find_module(mod_name)
else:
pkg_ident = ".".join(aux[:-1])
pkg_instance = get_module(pkg_ident)
if not hasattr(pkg_instance, "__path__"):
raise ValueError("package identifier is not a normal package: %r" % (pkg_ident, ))
fp, pathname, description, = imp.find_module(mod_name, pkg_instance.__path__)
try:
return imp.load_module(mod_name, fp, pathname, description)
finally:
if fp:
fp.close()
[docs]def iter_modules_in_package(package_ident, exclude_names=None):
# type: (str, str) -> iter[Any]
"""
取得指定套件 (package) 中的模組物件,這個函式只會取出指定套件中的第一層子模組,並不會遞迴列出所有深度的模組。
Get immediate module objects in given package. (will not yield recursively)
Args:
package_ident: 套件識別字串或是套件物件 / Package identifier string or package object
exclude_names=None: 要排除的模組名稱 / Names to exclude
Yield:
產出 (mod_name, mod_instance,) 型式的 tuple 物件,成員分別表示模組名稱與模組物件
Generates tuple object in (mod_name, mod_instance,) form. Represents module name and module object respectively.
"""
if isinstance(package_ident, basestring):
pkg_instance = get_module(package_ident)
if not hasattr(pkg_instance, "__path__"):
raise ValueError("given package identifier is not ordinary package folder: %r" % (package_ident, ))
elif hasattr(package_ident, "__path__"):
pkg_instance = package_ident
package_ident = package_ident.__name__
else:
raise ValueError("require package identifier or package object: package_ident=%r" % (package_ident, ))
pkg_path = pkg_instance.__path__
exclude_names = frozenset(iter_chain(exclude_names if exclude_names else (), ("__init__", )))
found_mod_names = set()
for _module_loader, mod_name, _ispkg, in iter_modules(pkg_path):
if mod_name not in exclude_names:
found_mod_names.add(mod_name)
for mod_name in found_mod_names:
try:
yield (
mod_name,
sys.modules[package_ident + "." + mod_name],
)
except KeyError:
pass
fp, pathname, description, = imp.find_module(mod_name, pkg_path)
try:
yield (
mod_name,
imp.load_module(mod_name, fp, pathname, description),
)
finally:
if fp:
fp.close()
# vim: ts=4 sw=4 ai nowrap