写这篇文章主要是对Python的import模块或包的机制有了更深层级的一个理解,也在具体工作中得到了一点实践,这种思考是由上一篇文章《__main__内置模块预加载Shotgun接口的妙用》触发的。如果你写过自定义的模块或包,你应该会发现import只会在第一次发生,如果修改代码需要通过reload来强制加载模块,这其中可以理解为Python在import的时候进行了动态加载机制将模块加载到内存当中,我们可以通过sys.modules来查看当前执行环境的内存中已经存在的模块,那如果理解成只要在sys.modules中已经加载过的模块是否就不需要import了呢?我们随便打开一个Python执行环境,你会发现事实并不是这个样子。

很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。

很多已经做案例的人,却不知道如何去学习更加高深的知识。

那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!

QQ群:127341871

我们看到上面的os模块在我们的sys.modules中,为何我使用os模块之前还需要import才能使用呢?如果你写过几个py文件构建的包,每个py文件中都要使用到os模块,正常操作在每个py文件中都需要import os代码才能运行,这样每次import不需要消耗内存和时间吗?

我们可以从《Python源码剖析》这本书的模块章节中找到一些答案

从Python的角度看,import其实并不完全等同于我们所熟知的“动态加载”这个概念,它的真实含义是希望某个module能够被感知,即是将这个module以某个符号的形式引入到某个名字空间。如果import等于动态加载,那么Python将对同一个module执行多次动态加载,并且在内存中保存一个module的多个映像,这显然是愚蠢的。

《Python源码剖析》第360页

理解起来有点晦涩,我们看一些代码来验证一下,通过dir()和id()两个内置函数来理解一下他所说的意思

通过交互环境反馈的结果你会惊奇地发现,这里的import os只是起到将os引入到当前的名字空间,通过两个对象在内存中的id可以看到import的os就是已经存在内存中的sys.modules中的os,也就是说这里的import os并没有真的去实例化一个os对象出来,而仅仅是起到引用内存中已存在的os对象。也就是说你在每一个py文件中import os并不会占用更多的内存与导入时间。

那我们想想Python为什么要这样做?既然都是调用sys.modules里的模块,为什么还要通过import来引入名字空间呢?这里要理解名字空间的含义,在我们打开一个Python执行环境的时候,Python就将一大批module加载到内存当中,但为了使local名字空间足够干净,Python没有将这些符号暴露在local名字空间中,而是需要我们显式地通过import机制通知Python,我需要将这个符号引入到local名字空间,以便我的程序能使用这个符号背后的对象。

上面讲的是内置模块引入操作,那么如果是我们自定义的一个模块myModule1会怎样?Python正常地操作流程会是在第一次import myModule1的时候将myModule1加载到sys.modules,也就是内存中,产生pyc文件,并引入当前的名字空间,如果再次import myModule1,它不会再去做动态加载内存的操作,而是直接从内存sys.modules中引入已经加载过的对象,所以就出现了我们需要重新打开执行环境或者reload才能得到我们修改代码的结果。

那么我们再思考一下,比如Houdini中,我如果在启动的时候偷偷将我的模块加载到内存中以达到下次import的时候只是引用它到名字空间以节省第一次加载所带来的时间消耗呢?是不是只要通过123.py先导入这个自定义模块就可以?对的,就是这样的操作,123.py是Houdini的一个启动会执行的脚本代码,具体可上官网查阅用法。

https://www.sidefx.com/docs/houdini/hom/locations.html

再想想,如果我想在myModule1中定义一个全局的变量会怎样?这个全局变量就会随着import myModule1引入名字空间中作为一个全局的实例化对象在Houdini随意调用,这也就是可以通过自定义的一个模块来管理咱们可能需要频繁或者加载时间消耗比较严重的模块或者实例化需要时间的对象,这也就是这篇文章《__main__内置模块预加载Shotgun接口的妙用》另一种最好的解决方案。

# 123.pyimport myModule1# myModule1.pysg = shotgun_api3.Shotgun("https://piedpiper.shotgunstudio.com",                          login="rhendriks",                          password="c0mPre$Hi0n")

之后不管是菜单工具,还是工具架工具,还是模块文件中去调用sg接口都可以使用下面的代码引入名字空间操作。​​​​​​​

import myModule1myModule1.sg.create() # 使用Shotgun API

Python模块import本质是什么?import是什么的更多相关文章

  1. python 全栈开发,Day29(昨日作业讲解,模块搜索路径,编译python文件,包以及包的import和from,软件开发规范)

    一.昨日作业讲解 先来回顾一下昨日的内容 1.os模块 和操作系统交互 工作目录 文件夹 文件 操作系统命令 路径相关的 2.模块 最本质的区别 import会创建一个专属于模块的名字, 所有导入模块 ...

  2. 小白的Python之路 day5 python模块详解及import本质

    一.定义 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能) 本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻辑上组织模块 ...

  3. Python 模块详解及import本质

    同在当前目录下的模块和包导入 模块定义 本质就是.py结尾的python文件. 用来从逻辑上组织python代码(变量,函数,类,逻辑) 文件名: test.py;  对应的模块名 : test 模块 ...

  4. Python模块详解以及import本质,获得文件当前路径os.path.abspath,获得文件的父目录os.path.dirname,放到系统变量的第一位sys.path.insert(0,x)

    模块介绍 1.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻 ...

  5. python模块介绍和 import本质

    模块的定义: 用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质上就是.py结尾的python文件. 包的定义: 用来从逻辑上组织模块的,本质上就是一个目录.(必须有一个__ ...

  6. Python:模块详解及import本质

    转于:http://www.cnblogs.com/itfat/p/7481972.html 博主:东大网管 一.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能), ...

  7. 模块详解及import本质

    一.模块的定义 用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能) 本质就是.py结尾的Python文件(文件名test.py,对应的模块名:test) 包:用来从逻辑上组织模块的 ...

  8. Python学习第二阶段,Day2,import导入模块方法和内部原理

    怎样导入模块和导入包?? 1.模块定义:代码越来越多的时候,所有代码放在一个py文件无法维护.而将代码拆分成多个py文件,同一个名字的变量互不影响,模块本质上是一个.py文件或者".py&q ...

  9. Python3 第五周大纲(模块,导入方法、import本质,导入优化,模块的分类)

    1.定义: 模块:逻辑上组织python代码(变量.函数.类.逻辑:实现一个功能,本质是.py结尾的文件) 2.导入方法 import module_name,module_name2,...... ...

随机推荐

  1. SpringBoot项目里,让TKmybatis支持可以手写sql的Mapper.xml文件

    SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里 ...

  2. MongoDB用户验证和权限管理

    官方参考页面: https://docs.mongodb.com/v3.6/tutorial/enable-authentication/ https://docs.mongodb.com/v3.6/ ...

  3. zhy2_rehat6_mysql02 - 5.7主从搭建.txt

    1.0------------锁库: mysql>FLUSH TABLES WITH READ LOCK; 这个命令是全局读锁定,执行了命令之后所有库所有表都被锁定只读.一般都是用在数据库联机备 ...

  4. 31(1).密度聚类---DBSCAN算法

    密度聚类density-based clustering假设聚类结构能够通过样本分布的紧密程度确定. 密度聚类算法从样本的密度的角度来考察样本之间的可连接性,并基于可连接样本的不断扩张聚类簇,从而获得 ...

  5. Python实现单链表数据的添加、删除、插入操作

    Python实现单链表数据的添加.删除.插入操作 链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结 ...

  6. 【docker构建】基于docker构建wordpress博客网站平台

    WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理系统(CMS)来使用. WordPre ...

  7. maven修改运行环境配置

    maven中自带的tomcat是6版本,比如我们想用tomcat7,jdk1.8,我们就要通过配置来改变. 改变方式如下 <build> <plugins> <plugi ...

  8. 基于STM32F429,Cubemx的SDHC卡的基本Fatfs文件移植

    本博文要求各位初步了解Fatfs文件系统 友情提示Fatfs官网:http://elm-chan.org/fsw/ff/00index_e.html 1.开发软件 keil5,Cube5.21 2.实 ...

  9. Nginx配置Tomcat8反向代理出现 java.lang.IllegalArgumentException: The character [_] is never valid in a domain name.

    在配置Nginx的反向代理,访问反向代理的路径而出现了异常 java.lang.IllegalArgumentException: The character [_] is never valid i ...

  10. .Netcore Swagger - 解决外部库导致的“Actions require an explicit HttpMethod binding for Swagger 2.0”

    现象: 项目中导入Ocelot后,swagger页面无法正常显示,查看异常发现 Ocelot.Raft.RaftController 中的 Action 配置不完全,swagger扫描时不能正确生成 ...