一,模块介绍
1.1 什么是模块?
一个函数封装一个功能,比如现在有一个软件,不可能将所有程序都写入一个文件,所以咱们应该分文件,组织结构要好,代码不冗余,所以要分文件,但是分文件,分了5个文件,每个文件里面可能都有相同的功能(函数),
怎么办?所以将这些相同的功能封装到一个文件中,谁用谁拿。
怎么拿?模块就是文件,存放一堆函数,谁用谁拿。
比如:我要策马奔腾共享人世繁华,应该怎么样?我应该骑马,你也要去浪,你是不是也要骑马。
模块是一系列常用功能的集合体,一个py文件就是一个模块。
1.2 为什么要使用模块.
#1、从文件级别组织程序,更方便管理 随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用 #2、拿来主义,提升开发效率 同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率,避免重复造轮子。 #ps: 如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
二 ,import
2.1 import的使用。
#模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,
且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象
增加了一次引用,不会重新执行模块内的语句),如下 import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果. 代码示例: ''' import tbjx import tbjx import tbjx import tbjx import tbjx ''' ''' 执行结果:只是打印一次: from the tbjx.py '''
2.2 第一次导入模块执行三件事。
#1.为源文件(tbjx模块)创建新的名称空间,在tbjx中定义的函数和方法若是使用到了global时访问的就是这个名称空间。 #2.在新创建的命名空间中执行模块中包含的代码,见初始导入import tbjx 提示:导入模块时到底执行了什么? 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. 事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放 入模块全局名称空间表,用globals()可以查看 #3.创建名字tbjx来引用该命名空间 这个名字和变量名没什么区别,都是‘第一类的’,且使用tbjx.名字的方式 可以访问tbjx.py文件中定义的名字,tbjx.名字与test.py中的名字来自 两个完全不同的地方。
ps:重复导入会直接引用内存中已经加载好的结果
2.3 为模块起别名。
为模块起别名的作用:
1,可以将过长的模块命名改成短的,便于操作。
import tbjx as sm sm.read1()
2,有利于代码的拓展,优化。
#mysql.py def sqlparse(): print('from mysql sqlparse') #oracle.py def sqlparse(): print('from oracle sqlparse') #test.py db_type=input('>>: ') if db_type == 'mysql': import mysql as db elif db_type == 'oracle': import oracle as db db.sqlparse()
2.5 导入多个模块
import sys,os,json # 可以这样写,但是不推荐 #推荐应该这样: import sys import os import json
三,from ... import ...
3.1 from...import...使用
from 模块名 import 方法
3.2 from...import... 与import对比
#唯一的区别就是:使用from...import...则是将spam中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接使用名字就可以了、无需加前缀:tbjx. #from...import...的方式有好处也有坏处 好处:使用起来方便了 坏处:容易与当前执行文件中的名字冲突
3.3 也支持as
from tbjx import read1 as read read()
3.4 一行导入多个。
from tbjx import read1,read2,name
3.5 from ... import *
#from spam import * 把spam中所有的不是以下划线(_)开头的名字都导入到当前位置 #大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题
四,py文件的两种功能
#编写好的一个python文件可以有两种用途: 一:脚本,一个文件就是整个程序,用来被执行 二:模块,文件中存放着一堆功能,用来被导入使用 #python为我们内置了全局变量__name__, 当文件被当做脚本执行时:__name__ 等于'__main__' 当文件被当做模块导入时:__name__等于模块名 #作用:用来控制.py文件在不同的应用场景下执行不同的逻辑(或者是在模块文件中测试代码) if __name__ == '__main__':
五,模块的搜索路径
模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
#模块的查找顺序 1、在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用 ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看 2、如果没有,解释器则会查找同名的内建模块 3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。