一.模块
1 什么是模块?
一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
2 为何要使用模块?
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用,
3.如何使用模块?
3.1 import
3.1.1建立spam.py,文件名spam.py,模块名spam
#spam.py print(‘from the spam.py‘) money = 1000 def read1(): print(‘spam->read1->money‘,money) def read2(): print(‘spam->read2 calling read‘) read1() def change(): global money money = 0
建立test.py文件
模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下
import spam ##只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次‘from the spam.py‘,当然其他的顶级代码也都被执行了,只不过没有显示效果. import spam import spam #运行结果 from the spam.py # import sys # print(sys.modules)
我们可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。
3.1.2每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
1 #测试一:money与spam.money不冲突 2 #test.py 3 import spam 4 money=10 5 print(spam.money) 6 7 ‘‘‘ 8 执行结果: 9 from the spam.py 10 1000 11 ‘‘‘
1 #测试二:read1与spam.read1不冲突 2 #test.py 3 import spam 4 def read1(): 5 print(‘========‘) 6 spam.read1() 7 8 ‘‘‘ 9 执行结果: 10 from the spam.py 11 spam->read1->money 1000 12 ‘‘‘
1 #测试三:执行spam.change()操作的全局变量money仍然是spam中的 2 #test.py 3 import spam 4 money=1 5 spam.change() 6 print(money) 7 8 ‘‘‘ 9 执行结果: 10 from the spam.py 11 1 12 ‘‘‘
3.1.3 总结:首次导入模块spam时会做三件事:
1.为源文件(spam模块)创建新的名称空间,在spam中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
2.在新创建的命名空间中执行模块中包含的代码,见初始导入import spam
1 提示:导入模块时到底执行了什么? 2 3 In fact function definitions are also ‘statements’ that are ‘executed’; the execution of a module-level function definition enters the function name in the module’s global symbol table. 4 事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放入模块全局名称空间表,用globals()可以查看
3.创建名字spam来引用该命名空间
1 这个名字和变量名没什么区别,都是‘第一类的’,且使用spam.名字的方式可以访问spam.py文件中定义的名字,spam.名字与test.py中的名字来自两个完全不同的地方。
3.1.4 为模块名起别名,相当于m1=1;m2=m1
1 import spam as sm 2 print(sm.money)