lazy_import源码解析(原创)
参考链接:
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源码解析(原创)的更多相关文章
- [原创]android开源项目源码解析(一)----CircleImageView的源码解析
CircleImageView的代码很简洁,因此先将此工程作为源码解析系列的第一篇文章. 解析说明都在代码里了. /* * Copyright 2014 - 2015 Henning Dodenhof ...
- 【原创】backbone1.1.0源码解析之View
作为MVC框架,M(odel) V(iew) C(ontroler)之间的联系是必不可少的,今天要说的就是View(视图) 通常我们在写逻辑代码也好或者是在ui组件也好,都需要跟dom打交道,我们 ...
- 【原创】backbone1.1.0源码解析之Collection
晚上躺在床上,继续完成对Backbone.Collection的源码解析. 首先讲讲它用来干嘛? Backbone.Collection的实例表示一个集合,是很多model组成的,如果用model比喻 ...
- HashMap源码解析 非原创
Stack过时的类,使用Deque重新实现. HashCode和equals的关系 HashCode为hash码,用于散列数组中的存储时HashMap进行散列映射. equals方法适用于比较两个对象 ...
- Spring-cloud & Netflix 源码解析:Eureka 服务注册发现接口 ****
http://www.idouba.net/spring-cloud-source-eureka-client-api/?utm_source=tuicool&utm_medium=refer ...
- jQuery整体架构源码解析(转载)
jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...
- solr&lucene3.6.0源码解析(四)
本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...
- solr&lucene3.6.0源码解析(三)
solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...
- android源码解析(十七)-->Activity布局加载流程
版权声明:本文为博主原创文章,未经博主允许不得转载. 好吧,终于要开始讲讲Activity的布局加载流程了,大家都知道在Android体系中Activity扮演了一个界面展示的角色,这也是它与andr ...
随机推荐
- English Conversations You Can Download for Free (Spoken English MP3/Audio Files)
If you want to download free English conversations, you’ve come to the right place. This page introd ...
- 【机器学习】随机森林 Random Forest 得到模型后,评估参数重要性
在得出random forest 模型后,评估参数重要性 importance() 示例如下 特征重要性评价标准 %IncMSE 是 increase in MSE.就是对每一个变量 比如 X1 随机 ...
- 【Java】学习笔记(1)
Java数据类型: 基本数据类型:(变量在栈中)数值型:byte(1个字节) short(2个字节) int(四个字节) long(8个字节) ,float(4字节) double(8字节) 字符型: ...
- Oracle 中DATE类型的计算
select sysdate,add_months(sysdate,12) from dual; --加1年 select sysdate,add_months(sysdate,1) f ...
- tomcat与iis公用80端口(已经发布.net项目现在开发Java项目时tomcat在eclipse中localhost:8080打不开问题)
在开发过.net项目的电脑上安装eclipse配置tomcat运行时打不开页面问题描述,这也是本人亲生经历,找了好多资料网上大多都是tomcat配置问题描述,今天突然想到是不是IIS的问题,果然上网一 ...
- 把excel每一行中的数据输出为一个txt文档的VBA函数
excel vba代码: Sub makeTxt() For i = 1 To 1088'从第1行到1088行(最后一行) On Error Resume Next'出现错误时继续运行脚本 Open ...
- java下载Excel模板(工具类)
一次文件下载记录 一次不成熟的文件下载操作记录,希望能对需要的人有所帮助. 1.前端代码 $("#downloadModel").click(function(){ var mod ...
- C++程序调用python3
今天想做一个简单的管理密码的小程序,由于最近了解了下Python,就想用Python来写.但是看了看Python的界面库用法有感觉有点麻烦,所以还不如直接使用MFC写写界面,关于csv的文件处理部分使 ...
- C#遍历SharePoint文档库下所有文档包括文档库中子文件夹下所有文档
/// <summary> /// 获取取子文件下所有文件 /// </summary> /// <param name="web"></ ...
- [转]JDBC如何进行超时设置
文档来源:https://jingyan.baidu.com/article/fc07f98922615a12ffe519ce.html 恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数 ...