定义:略!
先来一个模块spam.py
#spam.py print('from the spam.py') money=1000 def read1(): print('spam模块:',money) def read2(): print('spam模块') read1() def change(): global money money=0
import spam (从硬盘将spam读到内存中,执行一遍)
导入后,从上至下执行模块内部所有的代码。
结果是:from the spam.py
但是,在第二次导入的时候,就不用在执行模块里面的代码了。因为之前该模块已经加载过。
import spam #m1=111111 import spam #m2=m1 import spam import spam
总结:
# 导入模块,只会在第一次导入时执行源文件的代码 # 如果模块已经加载到内存了,下一次导入直接引用内存中导入的结果
下面看内存当中都加载了哪些模块:
import sys print(sys.modules) print('spam' in sys.modules)
字典形式列出;里面有上面的spam模块,因为spam之前已经加载完成了。
接下来,名称空间:
运行一个执行文件就会产生一个名称空间。import后又产生一个名称空间,至此这个“模块的使用.py”执行文件产生了两个名称空间,且两个内存空间是互相独立的。
#import 导入文件都做了哪些事? #1 以源文件(spam.py)为准产生一个名称空间 #2 以刚刚产生的名称空间为准,执行源文件的代码 #3 会在当前文件中(执行文件)定义一个名字(模块名),这个名字就是模块名,用来指向模块所在的名称空间,即可以调用里面的功能
import spam money=0 spam.read1() 结果: from the spam.py spam模块: 1000
类似:
import spam money=0 def read1(): print('from ------>') spam.read1()
下面这么写才能调用当前位置的read1
import spam money=0 def read1(): print('from ------>') read1() spam.read1()
再如:
import spam money=0 def read1(): print('from ------>') # read1() # spam.read1() spam.read2()
这里仍然执行spam里的read1
再如:
import spam money=0 money=1000000000 spam.change() print(money) 结果: from the spam.py 1000000000
这里change的是spam的money值。
import spam money=0 money=1000000000 spam.change() # print(money) spam.read1() 结果: from the spam.py spam模块: 0
这样可以看出change模块内部money值成功。
下面:
为模块起别名----
import spam as sm print(sm.money) 结果: from the spam.py 1000
也可以调用除了函数的其他变量
好处:
# 1、简化模块名称; # 2、调用方便,例子如下: 前提:两个模块,一个是mysql.py,另一个是oracle.py。 mysql.py代码如下: def parse(): print('mysql sql parse') oracle.py代码如下: def parse(): print('oracle sql parse') 就可以简化成如下: engine_type='mysql' if engine_type == 'mysql': import mysql as engine elif engine_type == 'oracle': import oracle as engine engine.parse()
另外,在一行导入多个模块
import spam,time
导入模块的另一种方法:
from...import...
好处是,在当前执行文件中用模块里的变量或函数的时候不用加.了。直接用变量或函数即可,不用再加前缀
坏处是,容易个当前文件里的名字冲突。
from spam import money,read1,read2,change # money=1 print(money) 结果: from the spam.py 1000 from spam import money,read1,read2,change money=1 print(money) 结果: from the spam.py 1
注意:不加前缀,优先从当前位置找变量或者函数。
from spam import money,read1,read2,change # money=1 # print(money) read1() def read1(): print('===>?') 结果: from the spam.py spam模块: 1000
哈哈,再注意:代码顺序;这里执行函数read1的时候,当前还没有定义好的read1函数,当前read1函数在后面了!
from spam import money,read1,read2,change # money=1 # print(money) read1() def read1(): print('===>?') # read1() read2()
read2调用的read1仍然是spam里的read1
from spam import money,read1,read2,change money=1 change() print(money) 结果: from the spam.py 1
print的仍然是当前文件定义的变量。
导入模块中的函数太多怎么办?
from spam import * print(money) print(read1) print(read2) print(change) 结果: from the spam.py 1000 <function read1 at 0x101c62510> <function read2 at 0x101c62620> <function change at 0x101c626a8>
导入模块中的全部变量,引起冲突的可能性更大,而且有的属性可能用不到,尽量少用。
Python模块内置变量__all__,列表形式,里面都是字符串(对应变量名、函数名等)
__all__=['money','read1'] #from ... import * 这样,*代表只导入了'money','read1'两个函数
* 对应模块spam内的__all__属性
如果被导入的模块没有__all__,*导入所有变量,如果被导入的模块有__all__。就以这个__all__后面的为准。
from也支持as
from spam import read1 as read
模块的重载:
程序需要重新启动才能利用改过的的模块程序。 也就是从硬盘读取新的内容加载到内存中。
不过,实验环境可以:
import importlib importlib.reload()
重新加载更新的模块。
需要在每个程序(需要使用更新后的模块)文件中重新加载。
py文件区分两种用途:模块与脚本
python文件都内置__name__
脚本时(spam): print(__name__) spam执行结果: from the spam.py __main__
如果,在执行文件中,import spam
spam里的加入print(__name__)
执行文件执行结果是
from the spam.py spam
总结:文件spam.py当做脚本执行,该值等于__main__,文件spam.py当做模块被导入时,该值等于spam
spam中加入:
if __name__ == '__main__': read1() read2() change() spam执行结果: from the spam.py spam模块: 1000 spam模块 spam模块: 1000
如果在执行文件中执行,就只有导入模块
import spam 结果: from the spam.py