模块详解

Posted zhouyixian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模块详解相关的知识,希望对你有一定的参考价值。

模块的使用

一、定义

1.什么是模块?

模块就是一系列功能的集合体

1.内置模块

2.第三方模块

3.自定义模块

模块的格式:

1.使用python编写的.py文件

2.已被编译成共享库或DLL的C或C++扩展

3.把一系列模块组织到一起的文件夹 (注:文件夹下有一个---init---.py的文件,该文件称之为包)

4.使用C编写并链接到python解释器的内置模块

2.为何要用模块?

1.使用内置或第三方的模块可以直接调用,极大提升开发效率

2.使用自定义模块的好处是可以减少代码冗余(抽取我们自己程序中要公用的一些功能定义成模块,然后程序的各部分组件都可以去模块中调用共享功能)

二.如何用模块

大前提:一定要区分开谁是执行文件,谁是被导入模块

注:导入模块会编译执行成一个pyc文件。

import导入模块:

1.首次导入模块

1.产生一个模块的名称空间

2.执行文件spam.py将执行过程中产生的名字都放到模块的名称空间

3.在当前执行文件的名称空间中拿到一个模块名

4.之后的导入都是直接引用第一次导入的成果,不会重新执行文件。

 #文件名是spam.py,模块名是spam
 #在执行文件中可以访问模块名称空间中名字的语法:模块名 加名字
  import spam
    print(spam.x) #指名道姓的调用

 

2.总结import导入模块:

1.在使用时必须加上前缀:模块名

优点:指名道姓的向某一个名称空间要名字,肯定不会与当前名称空间的名字冲突。

缺点:但凡应用模块中的名字必须加前缀,不够简洁

from ....import....导入模块

1.首次导入模块

1.产生一个模块的名称空间

2.执行文件spam.py将执行过程中产生的名字都放到模块的名称空间

3.在当前执行文件中直接拿到一个名字,该名字就是执行模块的名字。

#不用加前缀,更简洁,直接可以打印
from spam import money
print(money)
#注:from...import * ,*代表被导入模块中拿到(除了下划线外)所有名字(不推荐使用,容易与当前名称空间的名字冲突)

 

 

2.总结from ....import....:

优点:使用时无需再加前缀,更简洁

缺点:容易与当前名称空间中的名6565字冲突

注:函数的作用域关系在定义阶段就已经固定死了,与调用位置无关。一个文件就会产生一个全局名称空间,之间不互通,用as起别名后,原名字失效。

模块的循环导入问题

技术图片
‘‘‘
模块之间出现了环状导入,如:m1.py 中导入了m2,m2.py 中又导入了m1

循环导入的问题:
    -- 导入模块是要使用模块中的变量
    -- 正常逻辑都是在文件最上方先完成对模块的导入,再在下方定义自身模块变量,以及使用导入的模块中的变量
    -- 由于导入模块的特殊机制,第一次导入模块会编译执行导入的模块,也就是会进入模块逐句执行模块内容,再次导入只是使用内存中的名字
    -- 就会出现下面的情况,m2在使用m1中的变量x,但变量x却并未产生,这就出现了循环导入问题
    
m1.py文件
import m2
x = 10
print(m2.y)

m2.py文件
import m1
y = 10
print(m2.x)

解决循环导入的问题:延后导入
1、将循环导入对应包要使用的变量提前定义,再导入响应的包
2、将导包的路径放到函数体中,保证存放导包逻辑的函数调用在要使用的变量定义之后

重点:
问题:from导包极容易出现循环导入问题
解决:建议from导入方式改用import导入方式
‘‘‘
View Code

 

 

核心问题:两个模块之间相互导入,且互相使用其名称空间中的名字,但是有些名字没有产生就是用,就导致了循环导入的·问题,必须把需要导入的值定义好在调用

解决方案一:延后导入 - 先产生对方需要的变量,在进行导入,把循环导入的语句放到变量定义的后面

#在文件m2.py与m1.py  ,通过run文件来调用
#m1.py文件中
x=m1
from m2 import y
#m2.py文件中
y=m2
from m1 import x
?

 

 解决方案二:将导包的路径放到函数中,保证存放导包逻辑的函数调用再要使用的变量之后

#在文件m2.py与m1.py  ,通过run文件来调用
#m1.py
def f1():
    from m2 import y
    print(m1.f1---->y:y)
x=m1
#m2.py
def f2():
    from m1 import x
    print(m2.f1---->x:x)
y=m2

 

 

区分python文件的两种用途

#当文件被执行时_name_ == ‘_main_‘
#当文件被导入时_name_ == ‘模块名‘
直接使用快捷方式来进行判断区分
#示范:
def f1():
    print(f1)
def f2():
    print(f2)
if __name__ == __main__ #直接输入main回车会自动生成if判断
#在if 判断下面可以进行你自己的测试而不会存在文件导入时会直接将运行结果输出
f1()
f2()

模块的搜索路径

模块搜索路径的优先级

1.内存中已经加载过的

2.内置模块

3.sys.path(环境变量)#第一个值是当前执行文件所在的文件夹

强调:所有被导入的模块参照环境变量sys.path都是以执行文件为准的。
自己总结:如果需要被导入的模块不在当前执行文件的路径下,那么我们使用from ‘需要被导入模块的文件夹‘ import ‘需要导入的模块,或者将文件夹路径加入到sys.path里面‘
模块的绝对导入:以执行文件的sys.path为起始点开始导入,称之为绝对导入

优点:执行文件与被导入的模块中都可以使用

缺点:所有导入都是以sys.path为起始点,导入麻烦

模块的相对导入:参照当前所在文件的文件夹为起始点开始查找,称之为相对导入。

符号:‘ . ’代表当前所在文件的文件加‘ . ‘代表上一级文件夹

优点:导入简单

缺点:只能在被导入的模块中使用,不能再执行文件中使用

 

以上是关于模块详解的主要内容,如果未能解决你的问题,请参考以下文章

(转) Java中的负数及基本类型的转型详解

20160224.CCPP体系详解(0034天)

详解Android WebView加载html片段

如何有条件地将 C 代码片段编译到我的 Perl 模块?

CTS测试CtsWindowManagerDeviceTestCases模块的testShowWhenLockedImeActivityAndShowSoftInput测试fail项解决方法(代码片段

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段