python基础-模块导入
导入包
# 导入包的过程:就是执行包下面的__init__文件 # import导入包时候,点左边的都必须是包 # from...import...导入包时候,import后边不能有点 # 例如:在glance包下的api包下引入policy.py模块 # from glance.api import policy # 全部引入: # from glance.api import * # 其实*等价于__all__: from package.dir import hello print(hello.x) # 可以用import导入内置或者第三方模块, # 但是要绝对避免使用import来导入自定义包的子模块, # 应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。 import os,sys print(__file__) print(os.path.abspath(__file__)) base_path=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(base_path) sys.path.append(base_path) # 为了提高模块的加载速度,Python缓存编译的版本。 # 每个模块在__pycache__目录的以module.version.pyc的形式命名,通常包含了python的版本号, # 如在CPython版本3.3,关于spam.py的编译版本将被缓存成__pycache__/spam.cpython-33.pyc, # 这种命名约定允许不同的版本,不同版本的Python编写模块共存。 # # Python检查源文件的修改时间与编译的版本进行对比,如果过期就需要重新编译。这是完全自动的过程。 # 并且编译的模块是平台独立的,所以相同的库可以在不同的架构的系统之间共享,即pyc使一种跨平台的字节码, # 类似于JAVA.NET,是由python虚拟机来执行的,但是pyc的内容跟python的版本相关,不同的版本编译后的pyc文件不同, # 2.5编译的pyc文件不能到3.5上执行,并且pyc文件是可以反编译的,因而它的出现仅仅是用来提升模块的加载速度的。 # # 在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的
模块与包from导入
# 我们导入模块有可能重复导入,为了防止你重复导入,python的优化手段是: # 第一次导入后就将模块名加载到内存了, # 后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用, # 不会重新执行模块内的语句。 # 我们可以从sys.module中找到当前已经加载的模块, # sys.module是一个字典,内部包含模块名与模块对象的映射, # 该字典决定了导入模块时是否需要重新导入 # 查看是不是已经导入了,查看内存中是否有模块: import sys print(sys.modules) # 我这里有一个span.py 文件,里面的内容是虾面 # #spam.py # print('from the spam.py') # # money=1000 # # def read1(): # print('spam->read1->money',1000) # # def read2(): # print('spam->read2 calling read') # read1() # # def change(): # global money # money=0 from span import money,read1,read2 # 将span中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了,但是造成了冲突 print(money) print(read1()) print(read2()) print(__name__) if __name__=="__main__": print("文件被当作脚本执行")
模块与包import导入
import span # 导入时候,发生了什么? # 第一件事:创建名称空间,用来存放span.py中定义的名字, # 第二件事:基于刚刚创建的名称空间执行span.py文件 # 第三件事:创建名字spam指向该名称空间,来引用该命名空间,span.名字对操作,都是以这个为准 print(span.money) print(hasattr(span,"money")) # 反射为True
模块的搜索路径
# 我们可以通过模块的全局变量__name__来查看模块名: # 当做脚本运行: # __name__ 等于'__main__' # # 当做模块导入: # __name__= # # 作用:用来控制.py文件在不同的应用场景下执行不同的逻辑 # if __name__ == '__main__': # 所以总结模块的查找顺序是: # 1,内存中已经加载的模块 # 2,内建模块 # 3,sys.path路径中包含的模块,当前路径 # 某种场景下,其他路径模块导入就不行了,所以啊,我们不能把固定的结构目录放入内存和内建,只有加入sys.path # 最好不要建和内存,内建,第三方重名的文件名