原创

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://fungleo.blog.csdn.net/article/details/81390906

最近一直在写一套基于 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 原创,允许转载,但转载必须保留首发链接。

文章最后发布于: 2018-08-03 16:59:45
展开阅读全文
0 个人打赏
私信求帮助
曾参与过风云系列卫星、碳卫星、子午工程、嫦娥等项目的数据处理工作;有超10年大型项目的开发经验。 专栏收入了作者为Python爱好者精心打造的多篇文章,从小白入门学习的基础语法、基础模块精讲等内容外,还提出了“Python语感训练”的概念和方法,不仅为初学者提供了进阶之路,有一定基础的程序员亦可从中受益。后续,本专栏还将加入2D/3D应用开发、数据处理、实战项目等精品内容,敬请期待。
xufive ¥3.80 1544人订阅

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览