首页 > programming > 在 python 中动态导入模块

在 python 中动态导入模块

在模块化编程的时候, 有时候模块的名字和细节, 主模块是不清楚的, 为了实现动态载入 模块(运行时载入模块), 不同的编程语言有不同的处理方式, 如在 C/CPP 中的 dlopen 等.

在 python 中, 也有相应的处理机制, 这些机制可以避免我们在模块化编程的时候, 频繁的修改上层代码, 比如不断的 import 等.

以一个小程序为例, 该程序支持 add, remove 命令:

# foo add some
# foo remove some

为了支持更多的命令, 比较优雅的方式是把每个命令模块化, 在合适的时机导入/注册 这些模块, 而不是在上层接口不断的 import. 我们可以通过 setuptools 的 entry_points 来达到这个目的.

1 首先, 在 setup 中注册插件名称和加载函数, 在 entry_points 中设置插件的组, 和需要注册的插件(名称和load函数)

# @file setup.py
from setuptools import setup
 
setup(
    # Other keywords
    entry_points={
        'foo': [
            'add = add:make',
            'remove = remove:make',
            'update = update:make',
        ],
    }
)

2 分别编写 add.py, remove.py, update.py 这些模块, 在每个模块里面, 分别编写各 自的 load 方法, 方法名要和上面设置的(这里为 make)一致, 例如:

# file add.py
import os
 
 
def make():
    print "register %s" % os.path.splitext(os.path.basename(__file__))[0]

3 通过 pkg_resources, 获取相应的模块名和模块方法

# file foo.py
import pkg_resources
entry_points = [
    (ep.name, ep.load()) for ep in pkg_resources.iter_entry_points('foo')
    ]
for (name, fn) in entry_points:
    fn()

以后如果增加新的命令, 只需要修改 setup.py, 把模块名字和方法注册进去就可以了.

测试一下:

$ python setup.py sdist
$ python foo.py 
register add
register update
register remove

分类: programming 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.