-
2019-02-15 15:55:19
概述
在
Spring
中,如果想基于一个给定的选择标准(selection criteria
),比如一个或者多个注解属性导入一些配置类(使用@Configuration
的那些类),某个bean
注册器,可以实现接口ImportSelector
来实现这样的逻辑。一个
ImportSelector
实现类通常也可能会实现各种Aware
接口,如果实现了这些Aware
接口,这些接口方法的调用会发生在selectImports
之前。ImportSelector#selectImports
的调用在ConfigurationClassParser#processImports
中。实现类举例:
AutoConfigurationImportSelector
Springboot
用于从所有jar
包的META-INF/spring.factories
文件中加载所有的自动配置类:key
为org.springframework.boot.autoconfigure.EnableAutoConfiguration
的项。SessionAutoConfiguration$SessionConfigurationImportSelector
根据当前
Web
环境类型决定启用哪个Session
配置类。
一个
ImportSelector
通常被@Import
注解使用,如下所示 ://... @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { //... }
ImportSelector#selectImports
返回的树组的元素的类型可以是以下三种情况之一 :ImportSelector
(也就是说,一个ImportSelector
可以导入另外一个ImportSelector
)ImportBeanDefinitionRegistrar
- 某个配置类
源代码解析
package org.springframework.context.annotation; import org.springframework.core.type.AnnotationMetadata; public interface ImportSelector { /** * Select and return the names of which class(es) should be imported based on * the AnnotationMetadata of the importing @Configuration class. * * 这里importingClassMetadata是使用@Import注解导入该ImportSelector * 的配置类的注解元数据。实现类可以实现该方法,根据导入类的注解元数据 * 也就是importingClassMetadata,当然也可以结合考虑当前环境中的其他信息, * 决定导入哪些配置类。 */ String[] selectImports(AnnotationMetadata importingClassMetadata); }
有关文章
更多相关内容 -
MM模块概念导入讲解
2018-12-18 18:46:06MM模块概念导入讲解,从SAP MM模块基本概念、企业结构、主数据、采购管理、库存管理、发票校验几个方面讲解MM主要业务知识点。 -
ERP实施前期的用于概念导入的培训手册.doc
2022-06-19 04:12:30ERP实施前期的用于概念导入的培训手册 -
5S管理意识及概念导入基础知识专题讲座.pptx
2021-10-10 21:57:265S管理意识及概念导入基础知识专题讲座.pptx -
大数据-算法-课堂导入在高中数学概念教学中的实践研究.pdf
2022-05-06 16:51:01大数据-算法-课堂导入在高中数学概念教学中的实践研究.pdf -
详解JS模块导入导出
2020-11-28 13:05:10当然,上面提到有模块的概念,也是在JS用于服务器端编程的时候才会出现,我们在使用前端框架时,使用npm run dev,不就是启动了一个node服务。 对于JavaScript模块化编程的起源可以追溯到2009年,Ryan Dahl在github上... -
详解Python中的相对导入和绝对导入
2020-12-24 23:10:58Python 相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。 Python import 的搜索路径 在当前目录下搜索该模块 在环境变量 PYTHONPATH 中指定的路径列表中依次... -
将虚拟机导入CAS云计算平台步骤及参数修改
2020-04-09 16:32:45(一定要注意,在这里坑了很久,我明明什么都配置对了,但是就是连不通网络,就是因为没有修改为业务网)网上也看到有人导入后,虚拟机的IP无法访问,这里一定要注意!!!要是无法联通虚拟机网络,注意这里是不是...因项目需要在内网平台布置虚拟机,写此文档记录一下。公司的项目需要将虚拟机CentOS系统安装到CAS云计算管理平台,内网服务器。记录操作步骤如下:
一、 下载资源。
因为服务器内网不能联网,所以资源先要下载到本地PC。下载安装VMware WorkStation Pro 用于启动虚拟机,下载对应版本的CentOS镜像,用VMware WorkStation Pro加载虚拟机镜像。
二、 安装虚拟机。
根据教程安装虚拟机,完成虚拟机的安装配置。选择语言,时区,分配磁盘空间,设置虚拟机登录账号密码。
三、 设置虚拟机网络。
点击“编辑”菜单下的——>“虚拟机网络编辑器(N)”,进入网络配置界面。点击“更改设置”进行网络配置。
网络配置如下图所示:
第1步:选择Vmnet8这个虚拟机网卡,进行编辑。
第2步:将VMnet8网卡修改为“NAT模式”
第3步:配置“子网IP”和“子网掩码”
第4步:点击“NAT设置”进入设置界面
第5步:在“网关IP”一栏添加网关
第6步:点击“添加”按钮,添加虚拟机主机的IP地址。
第7步:添加主机端口为“80”,类型选择为“TCP”,虚拟机地址填写为自己设置的IP地址。
四、 进入虚拟机,用命令行配置IP地址等信息。使本地PC能访问虚拟机网络,在虚拟机下载文件、安装应用。(否则本地无法连接虚拟机IP,或者虚拟机中ens33网卡中没有IP地址)
在虚拟机的命令行输入指令,编辑网卡的网络信息。编辑命令:vi /etc/sysconfig/network-scripts/ifcfg-ens33(注意vi后面需要加空格)
BOOTPROTO=dncp修改为static,将dhcp自动分配IP地址改为静态IP(固定)
ONBOOT=no修改为yes,将网络改为开机自启状态
IPADDR=IP地址,此处需要自己添加的IP,需要与步骤三中虚拟机网络设置的IP一致
GATEWAY=网关,此处的IP网关需要自己添加,设置为IP地址的网关
NETMASK=子网掩码,此处的子网掩码需要自己添加,一般为255.255.255.0
五、 将虚拟机导出为OVA格式。
选中虚拟机,点击“文件”选项,选择“导出为OVF”选项。导出时默认是OVF格式,直接把后缀修改为.ova即可导出为ova格式(华三CAS云计算平台服务器只能导入.ova格式的文件)。如果是导出虚拟机给另一台装有VMware Workstation Pro的PC机使用,ovf或ova格式都可以使用,两种格式都能读取。
六、 将.ova格式的文件导入CAS云计算平台。(用谷歌浏览器登录,其他浏览器登录会直接卡死)输入IP和端口登录云计算平台 。
选择需要安装的服务器,鼠标右键选择“导入OVF模板”,将导出的.ova格式的虚拟机文件拖动到模板框。
把文件拖动到框内,点击“开始上传”将.ova文件上传到服务器,一直点“下一步”即可完成配置。
七、 修改虚拟机网络配置,点击进入修改界面。
- “虚拟交换机”这里默认是设备网,一定要修改为业务网,否则即使地址配置对了,也会一直ping不通网络,虚拟机网络会连不通。(一定要注意,在这里坑了很久,我明明什么都配置对了,但是就是连不通网络,就是因为没有修改为业务网)网上也看到有人导入后,虚拟机的IP无法访问,这里一定要注意!!!要是无法联通虚拟机网络,注意这里是不是可以更换另一个网络!!!
- “MAC地址”最好截图保存,后期要配置eth0网卡的地址,必须要有MAC地址,否则配置后的eth0网卡没有IP。
3.点击“应用”将设置保存。
八、 修改eth0网卡的IP地址,配置网卡。(内网使用的是eth0网卡,只要配置这个网卡就行)
使用命令行进行eth0网卡配置,改动下面三处位置即可。指令:vi /etc/sysconfig/network-scripts/ifcfg-eth0(vi后面要有空格)
BOOTPROTO=static,将网卡改为固定IP地址
NOBOOT=yes,将网卡设置为开机启动
HWADDR=MAC地址(这里要填写虚拟机的MAC地址,否则ifconfig指令显示eth0网卡没有IP地址)
IPADDR=设置一个内网的IP地址
GATEWAY=设置与IP地址同一网段的网关地址
NETMASK=255.255.255.0通用子网掩码
-
将powerDesigner的概念模型转换成物理模型,生成sql文件导入数据库.
2011-03-25 17:36:40将powerDesigner的概念模型转换成物理模型,生成sql文件导入数据库. -
包的概念和导入包的方法
2019-04-09 19:39:08包的概念:包是一种通过使用‘.模块名’来组织python模块名称空间的方式。通俗的讲包就是一系列模块的集合体 具体的:包就是一个包含有 __ init __ .py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将...包的认识
包的概念:包是一种通过使用‘.模块名’来组织python模块名称空间的方式。通俗的讲包就是一系列模块的集合体
具体的:包就是一个包含有 __ init __ .py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来使用包的目的:包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性
包名:包名就是存放一系列模块的文件夹名字
重点:
包中一定有一个专门用来管理包中所有模块的文件
包名(包对象)存放的是管理模块的那个文件的地址,指向其全局名称空间模块的加载顺序
模块的加载顺序:内存 => 内置 => sys.path(一系列自定义模块)
import sys sys.path ''' sys.path 就是环境变量:存放文件路径的列表 重点:默认列表第一个元素就是当前被执行文件所在的目录 ''' 我们可以自己往sys.path添加路径 sys.path.append(r'想导入的模块的绝对路径') 添加到环境变量最后,最后被查找 sys.path.insert(0, r'想导入的模块的绝对路径') 添加到指定索引,索引就决定了自定义模块的查找顺序
包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的。
import time 第一次导入:内存->内置->自定义,最终在自定义中找到,完成导入,并在内存中缓存模块的内存地址 import m1 print(m1.num) time.sleep(5) #利用延迟把对应文件m1删除 再次导入,从内存中就可以直接找到,即时当前文件为删除状态,内存中的地址任然可以被引用 import m1 as mm1 print(mm1.num)
模块导入的执行流程
''' 导入模块的指令: -- 相当于 函数名() 调用函数体,函数调用会进入函数体,从上至下逐句解释执行函数体代码 -- 导入模块,会进入模块文件,从上至下逐句解释执行模块文件代码 -- 如果在模块中又遇到导入其他模块,会接着进入导入的模块,从上至下逐句解释执行文件中代码,依次类推 '''
循环导入
模块之间出现了环状导入,如:m1.py 中导入了m2,m2.py 中又导入了m1
循环导入引发的问题:
两个模块直接相互导入,且相互使用其名称空间中的名字,但是有些名字没有产生就使用,就出现了循环导入问题。m1.py文件 import m2 x = 10 print(m2.y) m2.py文件 import m1 y = 10 print(m2.x)
两种解决循环导入的问题:延后导入
1、将循环导入对应包要使用的变量提前定义,再导入相应的包
2、将导包的路径放到函数体中,保证存放导包逻辑的函数调用在要使用的变量定义之后注意点:
from导入马上会使用名字,极容易出现错误,建议循环导入情况下,尽量使用import导入。包的导入
import本质:通过查找环境变量(sys.path)中的绝对路径来完成导入(右键执行该文件,sys.path第一个元素是当前文件夹路径)。
导包:
1.保证包所在文件夹在环境变量中
2.导入的文件夹名就是包名import pk ''' pk文件夹 -- __init__.py '''
导包完成的三件事
导包过程中会完成以下三件事:
1.编译执行包中的__ init __ .py 文件,会在包中__ pycache __ 创建对应的pyc文件
2.产生 __ init __ .py 文件的全局名称空间,用来存放 __ init __ 出现的名字
3.产生包名指向 __ init __ .py 文件的全局名称空间 | 指定变量名指向包中指定名字总结:包名为文件夹名,名称空间是 __ init __ .py 产生的
使用包中模块中的名字:采用import导入
注意点:
1.在包 __ init__ . py中不建议使用import导入
2、在包 __ init __ .py 中不建议使用as起别名
总结:不建议 __ init __ .py 中采用import管理名字 ==> 空着不写在使用文件中
直接在要使用的文件中用import一层层找到你想要的名字
import 包名.文件名 as 别名起完别名,原名不可以再使用
原名:包名.文件名 => 包名.文件名.变量名
别名:别名 => 别名.变量名绝对导入和相对导入
包中使用import导入:绝对导入
# 在包的__init__文件中 import 模块名 # 问题:所属包不在环境变量,报错 import 包名.模块名 # 问题:包所属文件夹不在文件变量,报错 import 包名.模块名 as 别名 # 在外界:包名.模块名 | 包名.别名 都可以访问 import 包名.模块名.名字 # 问题:导包语句.语法左侧必须全部是包(文件夹) 外界 import 包名 包名.名字 # 访问的是__init__中的名字 包名.模块 # 访问的模块这个地址 包名.模块.名字 # 访问的模块中的名字 import 包名.模块 包名.模块 # 访问的模块这个地址 包名.模块.名字 # 访问的模块中的名字 from 包名 import 模块 模块 # 访问的模块这个地址 模块.名字 # 访问的模块中的名字 from 包名.模块 import 名字 名字 # 访问的模块中的名字
包中使用from导入:相对导入
没有子包
1) pk包 -- __init__.py -- 名字 a = 10 -- pkm.py -- 名字 b = 20 在外界 import pk pk.a 访问a pk.b 访问b init管理文件 a不需要操作 from .pkm import b
有子包
1、pk包 -- __init__.py sub子包 -- __init__.py 名字 x = 10 -- subm.py 名字 y = 10 直接在外界访问内部名字时 import pk pk.x 访问x pk.y 访问y 在pk的init管理文件 from .sub import x from .sub.subm import 2、pk包 -- __init__.py sub子包 -- __init__.py 名字 x = 10 -- subm.py 名字 y = 10 直接在外界访问内部名字时 import pk pk.sub.x 访问x pk.sub.y 访问y 在pk的init管理文件:要产生sub名字 from . import sub => pk.sub 在sub的init管理文件:要产生x,y名字 x不需要操作 => pk.sub.x from .subm import y => pk.sub.y
需要注意:
有相对导入.语法的文件都不能自执行 -
html2anki:将html文件整理成能导入anki的资料
2021-05-16 15:57:17其中一些重要的和常用的概念\API\知识点需要我们熟记于心. 本工具的开发初衷, 是为了让刚刚入门的新手, 最大化掌握前人总结的学习资料内容. 将本工具和记忆神器 anki 配合使用, 快速录入权威资料, 免去了手动制卡的... -
Notion-to-Obsidian-Converter:转换导出的概念注释以与黑曜石一起使用
2021-04-14 04:19:25黑曜石转换器概念 这是一个简单的脚本,用于将导出的概念注释转换为黑曜石(或其他系统)。 用法 从概念>设置和成员>设置>导出内容>导出所有工作空间内容中下载概念数据 使用7-Zip解压缩数据(或比Window的默认值更... -
机构特征挖掘与创新概念设计方法 (2006年)
2021-04-23 04:52:00设计方法则导入系统化机构概念设计,提高设计层次,以挖掘出的大量信息为设计基础,汇整出机构设计规范,并将设计规范导入概念设计方法,获得可行机构设计.如此能充分运用现有机构获得创新机构设计 ,能更有效率且更能掌握... -
2018_2019学年高中数学第一章集合1.1.1集合的概念情境导学素材新人教B版必修1
2021-08-05 21:45:292018_2019学年高中数学第一章集合1.1.1集合的概念情境导学素材新人教B版必修1 -
PHP命名空间namespace定义及导入use用法详解
2020-12-18 02:16:52本文实例讲述了PHP命名空间namespace定义及导入use用法。分享给大家供大家参考,具体如下: 在PHP中,出现同名函数或是同名类是不被允许的。为防止编程人员在项目中定义的类名或函数名出现重复冲突,在PHP5.3中引入... -
简单了解python模块概念
2020-09-20 21:36:24主要介绍了简单了解python模块概念,具有一定借鉴价值,需要的朋友可以参考下 -
高等数学复数概念复数表示与运算PPT课件.pptx
2021-10-10 12:07:12高等数学复数概念复数表示与运算PPT课件.pptx -
POC开发服务器,允许您通过本机ES模块导入来导入* .vue文件。-JavaScript开发
2021-05-26 00:17:04@ vue / dev-server这是概念证明。 想象一下,您可以在浏览器中本地导入Vue单文件组件……而无需构建步骤。 在目录中,创建一个index.html:<div id =“> </ div>&l @ vue / dev-server这是概念证明。 想象一下,您... -
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
2020-09-17 15:55:07主要介绍了Python动态导入模块:__import__、importlib、动态导入的使用场景,结合实例形式分析了Python动态导入模块__import__、importlib基本概念、原理及动态导入的具体应用操作技巧,需要的朋友可以参考下 -
矿建测量中高程导入方法的研究
2020-05-24 21:30:54为了实现2个坐标系统的统一,便引入了联系测量的概念。联系测量包括平面联系测量与高程联系测量两部分,平面联系测量简称定向,高程联系测量简称为高程导入。对矿建测量中高程导入的几种方法进行了阐述,并对其在高程... -
pandas.Series 概念
2020-12-21 02:23:53# 导入numpy、pandas模块 import numpy import pandas a = numpy.random.rand(5) s = pandas.Series(a) print(s) print(type(s)) # 查看数据类型 # .index:查看series索引,类型为rangeindex print(s -
Python创建模块及模块导入的方法
2020-09-22 00:35:57主要介绍了Python创建模块及模块导入的方法,实例分析了模块的定义、导入及模块属性的使用技巧,并附带说明了包的概念与用法,需要的朋友可以参考下 -
LabVIEW中导入web服务器视频教程.zip
2019-09-19 03:04:10LabVIEW中导入web服务器视频教程zip,本讲介绍了Web服务的概念,并且演示如何使用LabVIEW中“导入Web服务”,将网上已经发布的Web服务导入本地LabVIEW。 -
webpack-external-import:从其他Webpack捆绑包动态导入模块。 单独应用之间的无痛代码共享
2021-05-02 13:10:31Webpack外部导入 import()来自第三方的其他块和模块,或其他webpack自己构建!... 重大改写采用了原始概念并将其直接构建到webpack运行时中。 此发行版中的一大成就是树状支持 如果您想了解该工具 -
import-maps:如何控制JavaScript导入的行为
2021-05-04 08:50:38相邻概念为每个模块提供带外元数据 进一步的工作 多个导入地图支持 程序化API 后备支持 import: URL import.meta.resolve() 内置模块重映射 社区填料和工具 致谢 基本思路 该提议允许控制JavaScript import语句... -
python 模块导入详解
2020-11-29 19:08:16本文不讨论 Python 的导入机制(底层实现细节),仅讨论模块与包,以及导入语句相关的概念。通常,导入模块都是使用如下语句:import...import... as ...from ... import...from ... import ... as ...一般情况下,...本文不讨论 Python 的导入机制(底层实现细节),仅讨论模块与包,以及导入语句相关的概念。通常,导入模块都是使用如下语句:
import...import... as ...from ... import...from ... import ... as ...
一般情况下,使用以上语句导入模块已经够用的。但是在一些特殊场景中,可能还需要其他的导入方式。例如 Python 还提供了 __import__ 内建函数和 importlib 模块来实现动态导入。动态导入的好处是可以延迟模块的加载,仅在用到模块时才支持导入动作。
运用 __import__ 函数和 importlib 模块固然能够实现模块的延迟加载,但其不足之处是,在任何需要用到指定模块的地方都要实现一遍同样的导入语句,这样是不便于维护且非常麻烦的。如果能够在顶层实现惰性导入,则是一个更好的选择,这也是本文最终要讨论的点。
在讨论一些高级用法之前,首先需要了解一下模块与包的概念。
模块与包
模块 可以理解为是 Python 可以加载并执行的代码文件,代码文件不仅可以是 .py 文件,还可以是 .so 等其他类型的文件。Python 只有一个 模块 对象型态,而且所有模块都是这个型态。为了便于组织多个模块并提供一个模块层次结构的命名,Python 提供了 包 的概念。
可以简单的将包看作是一个文件系统的目录,将模块看作是目录中的代码文件(注意,不能完全地这样认为,因为包和模块并非仅来自文件系统,还可以来自压缩文件、网络等)。类似于文件系统的目录结构,包被分级组织起来,而且包本身也可以包含子包和常规模块。
包其实可以看作是一种特殊的模块。例如常规包(下面会介绍常规包的概念)的目录中需要包含 __init__.py 文件,当包被导入时,该文件的顶层代码被隐式执行,就如同模块导入时顶层代码被执行,该文件就像是包的代码一样。所以 包是一种特殊的模块。需要记住的是,所有的包都是模块,但不是所有的模块都是包。包中子包和模块都有 __path__ 属性,具体地说,任何包含 __path__ 属性的模块被认为是包。所有的模块都有一个名称,类似于标准属性访问语法,子包与他们父包的名字之间用点隔开。
Python 定义了两种类型的包,即 常规包 和 命名空间包。常规包是存在于 Python 3.2 及更早版本中的传统包。常规包即包含 __init__.py 文件的目录。当导入一个常规包时,__init__.py 文件被隐式执行,而且它定义的对象被绑定到包命名空间中的名称。 __init__.py 文件能包含其他任何模块能够包含的相同的 Python 代码,而且在导入时,Python 将给模块增加一些额外的属性。
从 Python 3.3 开始,Python 引入了 命名空间包 的概念。命名空间包是不同文件集的复合,每个文件集给父包贡献一个子包,所有的包中都不需要包含 __init__.py 文件。文件集可以存于文件系统的不同位置。文件集的查找包含导入过程中 Python 搜索的压缩文件,网络或者其他地方。命名空间包可以但也可以不与文件系统的对象直接对应,它们可以是真实的模块但没有具体的表述。更新关于命名空间包的说明可以参考 PEP 420。
命名空间包的 __path__ 属性与常规包不同,其使用自定义的迭代器类型,遍历所有包含该命令空间包的路径。如果他们父包的路径(或者高阶包的 sys.path )改变,它将在下次试图导入时在该包中自动重新搜索包部分。
如有如下目录结构:
.
├── bar-package
│ └── nsp
│ └── bar.py
└── foo-package
└── nsp
└── foo.py
则 nsp 即可以是一个命名空间包,以下是测试代码(记得用 Python 3.3 及更高版本运行测试):
importsys
sys.path.extend(['foo-package', 'bar-package'])importnspimportnsp.barimportnsp.fooprint(nsp.__path__)#输出:#_NamespacePath(['foo-package/nsp', 'bar-package/nsp'])
命名空间包具有如下特性:
1、优先级最低,在已有版本所有的 import 规则之后
2、包中不必再包含 __init__.py 文件
3、可以导入并组织目录分散的代码
4、依赖于 sys.path 中从左到右的搜索顺序
__import__
__import__ 函数可用于导入模块,import 语句也会调用函数。其定义为:
__import__(name[, globals[, locals[, fromlist[, level]]]])
参数介绍:
name (required): 被加载 module 的名称
globals (optional): 包含全局变量的字典,该选项很少使用,采用默认值 global()
locals (optional): 包含局部变量的字典,内部标准实现未用到该变量,采用默认值 - local()
fromlist (Optional): 被导入的 submodule 名称
level (Optional): 导入路径选项,Python 2 中默认为 -1,表示同时支持 absolute import 和 relative import。Python 3 中默认为 0,表示仅支持 absolute import。如果大于 0,则表示相对导入的父目录的级数,即 1 类似于 ‘.’,2 类似于 ‘..’。
使用示例:
#import spam
spam = __import__('spam')#import spam.ham
spam = __import__('spam.ham')#from spam.ham import eggs, sausage as saus
_temp = __import__('spam.ham', fromlist=['eggs', 'sausage'])
eggs=_temp.eggs
saus= _temp.sausage
模块缓存
在执行模块导入时,Python 的导入系统会首先尝试从 sys.modules 查找。sys.modules 中是所有已导入模块的一个缓存,包括中间路径。即,假如 foo.bar.baz 被导入,那么,sys.modules 将包含进入 foo,foo.bar 和 foo.bar.baz 模块的缓存。其实一个 dict 类型,每个键都有自己的值,对应相应的模块对象。
导入过程中,首先在 sys.modules 中查找模块名称,如果存在,则返回该模块并结束导入过程。如果未找到模块名称,Python 将继续搜索模块(从 sys.path 中查找并加载)。sys.modules 是可写的,删除一个键会使指定模块的缓存实现,下次导入时又将重新搜索指定的模块,这类似于模块的 reload。
需要注意的是,如果保持模块对象引用,并使 sys.modules 中缓存失效,然后再重新导入指定的模块,则这两个模块对象是不相同的。而相比之下,importlib.reload() 重新加载模块时,会使用相同的模块对象,并通过重新运行模块代码简单地重新初始化模块内容。
imp 与 importlib 模块
imp 模块提供了一些 import 语句内部实现的接口。例如模块查找(find_module)、模块加载(load_module)等等(模块的导入过程会包含模块查找、加载、缓存等步骤)。可以用该模块来简单实现内建的 __import__ 函数功能:
importimpimportsysdef __import__(name, globals=None, locals=None, fromlist=None):#首先从缓存中查找
try:returnsys.modules[name]exceptKeyError:pass
#如果模块缓存中没有,则开始从 sys.path 中查找模块
fp, pathname, description =imp.find_module(name)#如何找到模块则将其载入
try:returnimp.load_module(name, fp, pathname, description)finally:iffp:
fp.close()
importlib 模块在 python 2.7 被创建,并且仅包含一个函数:
importlib.import_module(name, package=None)
这个函数是对 __import__ 的封装,以用于更加便捷的动态导入模块。例如用其实现相对导入:
importimportlib#类似于 'from . import b'
b = importlib.import_module('.b', __package__)
从 python 3 开始,内建的 reload 函数被移到了 imp 模块中。而从 Python 3.4 开始,imp 模块被否决,不再建议使用,其包含的功能被移到了 importlib 模块下。即从 Python 3.4 开始,importlib 模块是之前 imp 模块和 importlib 模块的合集。
惰性导入
前边介绍的大部分内容都是为实现惰性导入做铺垫,其他的小部分内容仅是延伸而已(就是随便多介绍了点内容)。惰性导入即延迟模块导入,在真正用到模块时才执行模块的导入动作,如果模块不被使用则导入动作永远不会发生。
惰性导入的需求还是很常见的。一般推荐模块仅在顶层导入,而有时候在顶层导入模块并非最好的选择。比如,一个模块仅在一个函数或者类方法中用到时,则可使用局部导入(在局部作用域中执行导入),使得仅在函数或方法被执行时才导入模块,这样可以避免在顶层名字空间中引入模块变量。再比如,在我工作所负责的项目中,需要用到 pandas 包,而 pandas 包导入了会占用一些内存(不是很多,但也不算少,几十兆的样子),所以当不会用到 pandas 包时,我们希望他不被导入。我们自己实现的一些包在载入时会很耗时(因为要读取配置等等,在导入时就会耗时几秒到十几秒的样子),所以也极其需要惰性导入的特性。
下面是惰性导入的简单实现,可供参考:
importsysfrom types importModuleTypeclassLazyModuleType(ModuleType):
@propertydef_mod(self):
name= super(LazyModuleType, self).__getattribute__("__name__")if name not insys.modules:__import__(name)returnsys.modules[name]def __getattribute__(self, name):if name == "_mod":return super(LazyModuleType, self).__getattribute__(name)try:return self._mod.__getattribute__(name)exceptAttributeError:return super(LazyModuleType, self).__getattribute__(name)def __setattr__(self, name, value):
self._mod.__setattr__(name, value)def lazy_import(name, package=None):if name.startswith('.'):if notpackage:raise TypeError("relative imports require the 'package' argument")
level=0for character inname:if character != '.':breaklevel+= 1
if not hasattr(package, 'rindex'):raise ValueError("'package' not set to a string")
dot=len(package)for _ in range(level, 1, -1):try:
dot= package.rindex('.', 0, dot)exceptValueError:raise ValueError("attempted relative import beyond top-level"
"package")
name= "{}.{}".format(package[:dot], name[level:])return LazyModuleType(name)
参考资料
-
elasticSearch核心概念的介绍(八):批量导入和Term多种查询
2022-02-21 11:31:14elasticSearch核心概念的介绍(七):常见的数据类型 这里我们来介绍一下ES的批量导入数据 Bulk ES提供了一个叫bulk的API来进行批量导入操作 批量导入 数据 {“index”:{"_index":“book”,"_type":"_doc... -
操作系统论文——进程的概念与状态.docx
2020-10-30 10:17:11本文主要是介绍进程的一些基本概念与管理应用。进程是操作系统中最重要、最基本的概念之一。...一切仅具有静态特征的概念,例如程序,不能反映系统的上述特征,因此,导入了具有动态特征的进程概念。 -
1.1 -1.2 计算机网络的引入与基本概念
2018-06-19 20:04:371.1 -1.2 计算机网络的引入与基本概念 . -
数据库系统概念大学模式sql文件
2017-10-05 15:55:41数据库系统概念 的大学模式,instructor,student,teaches,takes等等,完整版