python 常用代码段汇总(四) 动态获取类或者函数 pkgutil 动态引入模块

最近一直在写一套基于 pythonsanic web 框架库的 restFul 接口的底层框架。由于我是初学,挑战这个任务基本上是属于不自量力型的。但目前我核心构架已经完全写出来了,我会在近期整理好相关资料后,写一系列的文章分享给大家。

这个挑战的过程很简单,因为大家知道我只是一个前端工程师。但是挑战的过程充满乐趣,今天,我就将我遇到的一些小的知识点,做一个汇总,也方便以后自己查找和复习。

根据字典键名查看键值不会报错的方法

一般情况下,我们会用类似 someDict['keyName'] 的方法,来获取键值内容。但是,如果这个键名不存在的话,就会报错。所以,在不确定的地方,推荐使用 get 方法来进行获取。就像 someDict.get('keyName') 这样。

实际运行效果如下:

根据字典键名查看键值不会报错的方法

如上图所示,这样取是不会报错的,只是没有返回而已。

根据字符串动态获取或执行类或函数

例如,我们在 model.py 这个文件中,有一个 class Test 的一个类。我们当然可以使用 from model import Test 这样的代码来进行引入。

但是问题是,如果你这个 Test 是通过程序动态计算出来的,你根本就不知道这个字符串具体是什么,改怎么办呢?

其实,解决方法非常简单,演示代码如下:

import model
classModel = getattr(model, 'Test')

这样,我们就拿到了这个 Test 的类了。并赋予了变量 classModel ,我们可以用这个变量去做应该做的事情了。

上面是演示了类根据字符串名称引入的方法。事实上,如果是 def 函数,也同样是可以用 getattr 函数引用。

因为这样的参数,让我们可以写出来非常灵活的代码。

pkgutil 动态引入模块

引入模块的方法非常简单,只要 import os 这样就可以引入了。但是,和上面一样,你会在一个文件夹中写越来越多的功能各异的业务代码,然后交给程序统一处理,这里,就需要动态引入了。

这里,我们使用 pkgutil 来实现这个功能,演示代码如下:

import pkgutil
# 引入存放未知模块的目录名称
import process
modules = {}
for _, name, __ pkgutil.iter_modules(process.__path__):
    m = _.find_module('process.' + name).load_module('process.' + name)
    modules[name] = m

然后,我们就可以用 modules[name] 来使用这个未知模块了。

其实 process.__path__ 就是一个文件夹路径的列表而已,并且,它还支持相对路径,所以上面的代码可以优化为如下代码:

import pkgutil

r = 'process'
modules = {}
for _, name, __ pkgutil.iter_modules([r]):
    m = _.find_module(r + '.' + name).load_module(r + '.' + name)
    modules[name] = m

好,连事先引入文件夹都省了。但上面的代码,是单层目录,如果是多层目录应该怎么办呢?那就这样写:

import pkgutil
r = 'process'
modules = {}
for x, n, _ in pkgutil.iter_modules([r]):
    m = x.find_module(r + '.' + n).load_module(r + '.' + n)
    for xx, nn, __ in pkgutil.iter_modules([r + '/' + n]):
        mm = xx.find_module(r + '.' + n + '.' + nn).\
                load_module(r + '.' + n + '.' + nn)
        for xxx, nnn, ___ in pkgutil.iter_modules([r + '/' + n + '/' + nn]):
            mmm = xxx.find_module(r + '.' + n + '.' + nn + '.' + nnn).\
                    load_module(r + '.' + n + '.' + nn + '.' + nnn)
            modules[n+nn+nnn] = mmm

我写的代码中,用到了一个三层的未知模块引入,所以,我写了上面这段代码。我表示呵呵~

每一个文件夹中,都必须包含 __init__ 文件,否则文件夹不会被自动识别为模块。

本文由 FungLeo 原创,允许转载,但转载必须保留首发链接。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页