参考链接:

An approach to lazy importing in Python 3.7(这个是参考源)

Python3.7中一种懒加载的方式(中文翻译)

原博客核心:

以前的两种惰性/延迟加载方法:

  ①本地子功能区加载而非程序启动时的全局加载。直到你的程序运行需要这个库的时候才进行加载;缺点:易重复载入库文件、容易遗忘库载入的范围。

  ②惰性加载。需要模块的时候触发 ModuleNotFoundError  提前发现这个模块,而延迟的只是后续补加载过程;缺点:显式优于隐式、如果一个模块希望立即加载,那么在延迟加载时,它可能会严重崩溃。(Mercurial实际上开发了一个模块黑名单,以避免延迟加载来解决这个问题,但是他们必须确保对其进行更新,因此这也不是一个完美的解决方案。)

博主提出来的最新的方法:

  在Python 3.7中,模块现在可以在其上定义__getattr__(),允许编写一个函数,在模块上的属性不可用时导入模块。这样做的缺点是使它成为一个惰性导入而不是一个加载,因此很晚才发现是否会引发ModuleNotFoundError。但是它是显式的,并且仍然是为您的模块全局定义的,因此更容易控制。

改进方向:发现导入错误被推迟,如何提前获知这个可能出现的导入错误防止程序抛出异常并终止。

代码段1:demo1.py

 import importlib

 # 这个是实现lazy_import的功能函数
def lazy_import(importer_name, to_import):
module = importlib.import_module(importer_name) # 直接加载调用的后一级函数 import_mapping = {} # 字典 键名:有可能为缩写名 值名:为原始可查找库名,例如:import_mapping['np'] = 'numpy'
for name in to_import:
importing, _, binding = name.partition(' as ')
if not binding:
_, _, binding = importing.rpartition('.')
import_mapping[binding] = importing def __getattr__(name):
if name not in import_mapping: # 如果这个库没在import_mapping中,就抛出异常错误,并且中断
message = f'module {importer_name!r} has no attribute {name!r}'
raise AttributeError(message)
importing = import_mapping[name]
imported = importlib.import_module(importing,module.__spec__.parent)
# print('name=',name,'module=',module,'module.__spec__=',module.__spec__,'module.__spec__.parent=',module.__spec__.parent)
setattr(module, name, imported) # sub, np, numpy
return imported return module, __getattr__ #返回一个库和一个方法

代码段2:sub.py

lazy_import 在python3.7中已经可以直接使用了
 # In pkg/__init__.py with a pkg/sub.py.
import demo1 # print('sub.py中的__name__ =', __name__)  #当其他程序调用这个程序的时候 __name__ = 'sub',自己为主程序的时候为 '__main__',这里我第一次使用的时候就出错了,直接在这个程序中测试
mod, __getattr__ = demo1.lazy_import(__name__, {'sys', '.sub as thingy', 'numpy as np'}) def test1():
print('sys运行正常')
return mod.sys def test2():
return mod.thingy.answer def test3():
print('numpy运行正常')
return mod.np

代码段3:mid_test.py

 import sub

 ### 异常检测,str_out是不存在的,抛出异常处理
# module1 = sub.str_out() module2 = sub.test3()
print(module2)
# <module 'numpy' from 'C:\\ProgramData\\Anaconda3\\envs\\lib\\site-packages\\numpy\\__init__.py'> print(module2.array([1, 2, 3, 4]))
# [1 2 3 4] print(module2.__spec__)
# ModuleSpec(
# name='numpy',
# loader=<_frozen_importlib_external.SourceFileLoader object at 0x000001E4879A6F98>,
# origin='C:\\ProgramData\\Anaconda3\\envs\\lib\\site-packages\\numpy\\__init__.py',
# submodule_search_locations=['C:\\ProgramData\\Anaconda3\\envs\\lib\\site-packages\\numpy']) print(module2.__spec__.parent)
# numpy

lazy_import源码解析(原创)的更多相关文章

  1. [原创]android开源项目源码解析(一)----CircleImageView的源码解析

    CircleImageView的代码很简洁,因此先将此工程作为源码解析系列的第一篇文章. 解析说明都在代码里了. /* * Copyright 2014 - 2015 Henning Dodenhof ...

  2. 【原创】backbone1.1.0源码解析之View

    作为MVC框架,M(odel)  V(iew)  C(ontroler)之间的联系是必不可少的,今天要说的就是View(视图) 通常我们在写逻辑代码也好或者是在ui组件也好,都需要跟dom打交道,我们 ...

  3. 【原创】backbone1.1.0源码解析之Collection

    晚上躺在床上,继续完成对Backbone.Collection的源码解析. 首先讲讲它用来干嘛? Backbone.Collection的实例表示一个集合,是很多model组成的,如果用model比喻 ...

  4. HashMap源码解析 非原创

    Stack过时的类,使用Deque重新实现. HashCode和equals的关系 HashCode为hash码,用于散列数组中的存储时HashMap进行散列映射. equals方法适用于比较两个对象 ...

  5. Spring-cloud & Netflix 源码解析:Eureka 服务注册发现接口 ****

    http://www.idouba.net/spring-cloud-source-eureka-client-api/?utm_source=tuicool&utm_medium=refer ...

  6. jQuery整体架构源码解析(转载)

    jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...

  7. solr&lucene3.6.0源码解析(四)

    本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...

  8. solr&lucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...

  9. android源码解析(十七)-->Activity布局加载流程

    版权声明:本文为博主原创文章,未经博主允许不得转载. 好吧,终于要开始讲讲Activity的布局加载流程了,大家都知道在Android体系中Activity扮演了一个界面展示的角色,这也是它与andr ...

随机推荐

  1. Core DES加、解密

    安装 Portable.BouncyCastle Nuget包 地址:https://www.nuget.org/packages/Portable.BouncyCastle/ Install-Pac ...

  2. matplotlib中color可用的颜色

    http://stackoverflow.com/questions/22408237/named-colors-in-matplotlib 参考网址给出了matplotlib中color可用的颜色: ...

  3. win10与虚拟机fedora14使用samba文件共享

    参考路径:http://blog.sina.com.cn/s/blog_ae9507be01017tyz.html 最近需要配置samba,试了好多次,终于搞定.奉上配置及共享文件的过程,以供参考. ...

  4. 小程序跳转tabbar页面

    如果在app.json 配置tabbar 的时候配置了 跳转的页面的链接: 在其余的子页面,设置用navigator 进行跳转会发现 在tabbar 设置过的页面无法进行跳转,这时需要在navigat ...

  5. 微信小程序开发之搞懂flex布局3——Flex Item

    Flex Item flex容器的子元素就是这个容器的flex item. The direct children of a Flex Container (elements with display ...

  6. Mac 系统搭建ThinkPHP3.2

    PHP3.2完整包目录 拷贝两个文件 index.php 和ThinkPHP目录到服务器目录中,我已经设置服务器目录与eclipse工作空间为同一个 创建TestThinkPHP 项目 Eclipse ...

  7. Nikto主动扫描神器!!!

    Perl语言开发的开源web安全扫描器 Nikto只支持主动扫描:可扫描web服务器类型是不是最新版本(分析先版本与新版相比有哪些漏洞) 针对:1.软件版本.2.搜索存在安全隐患的文件.3.服务器配置 ...

  8. final,finally,finalize

    final:可以修饰属性,可以修饰方法(方法不能被重写,可以继承),可以修饰类(该类不能被继承,不能产生子类) finally:无论什么情况,都会执行 finalize:垃圾回收时,调用此方法

  9. Visual Studio Code 学习记录

    Visual Studio Code的官方文档可以学到很多知识,不只是vs code的用法,包括一些语言的入门 和一些概念等等.很好的文档. ※,user.settings.json中的一些配置说明: ...

  10. media 标签解释

    一:常用标签这句话是自动设置缩放,然而,它并不能完全适应所有的手机,并且你在用浏览器手机模式调试的时候可能正常,但是换到真实的手机端其实是不正常的.所以我们还要进行改动. <meta name= ...