Python-模块

定义:略!

先来一个模块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
spam.py

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

 

posted @ 2017-10-19 19:57  大雄猫  阅读(167)  评论(0编辑  收藏  举报