01 模块导入 、包介绍

一、模块基本认识

1.1 什么是模块:
    模块:就是一系列功能的结合体

1.2 模块的三种来源:
            1.内置的(python解释器自带)
            2.第三方的(别人写的)
            3.自定义的(你自己写的)
1.3 模块的四种表现形式:
            1.py文件: 使用python编写的py文件(也就意味着py文件也可以称之为模块:一个py文件也可以称之为一个模块)
              2.共享库:  使用C编写并连接到python解释器的内置模块
              3.一系列模块文件的结合体(包):  把一系列模块组织到一起的文件夹(文件夹下有一个__init__.py文件,该文件夹称之为包)
            4.已被编译为共享库或DLL的C或C++扩展(了解)
1.5 为什么要用模块(提高开发效率 减少代码冗余 使项目结构更加清晰)
           1.内置的,第三方:典型的拿来主义,极大的提高开发效率
           2.自定义的:当程序比较庞大的时候,你的项目不可能只在一个py中,那么当多个文件中都需要使用相同的方法的时候
可以将该公共的方法写到一个py文件中其他的文件以模块的形式导过去直接调用即可
1.6 如何区分哪个是执行文件,哪个是被导入文件(******print(__name__): 1.当文件被当做执行文件执行的时候__name__打印的结果是__main__ 2.当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀) 3. if __name__ == '__main__': #快捷方法:写出main直接按tab 后面的加引号

 二、模块导入方式

更多内容见链接

2.1 import os #导入模块一定不要加后缀名

#导入过程 
 import md  
#import md  多次导入不会再执行模块文件,会沿用第一次导入的成果(******)  再次调用时python会查找名称空间,一旦发现就直接使用不再重复调用
    1.右键运行run.py文件首先会创建一个run.py的名称空间
    2.首次导入模块(md.py)(******)
        1.执行md.py文件,创建md的名称空间
        2.运行md.py文件中的代码将产生的名字与值存放到md.py名称空间中
        3.在执行文件中产生一个指向模块名称空间的名字(md)
        
#访问模块中变量        md.money  # 访问md模块中的money  1.指名道姓的访问模块中的名字 永远不会与执行文件中的名字冲突
                                                    2.你如果想访问模块中名字 必须用模块名.名字的方式
#访问模块中函数
md.change()  #会调用md中的change函数
1.只要你能拿到函数名 无论在哪都可以通过函数加括号来调用这个函数(会回到函数定义阶段 依次执行代码)
2.函数在定义阶段 名字查找就已经固定死了 不会因为调用位置的变化而改变

#分次导入原则 
导入模块通常情况情况下应该 分多次导入 结构清晰
import os 
import time
import md
ps:通常导入模块的句式会写在文件的开头(函数中也可能会有,这样不调用函数不调用模块省内存)

#给模块起外号
import ttttttttttttttttttttt  as f
f.name  #访问ttttttttttttttttt中的name
当模块名字比较复杂的情况下 可以给该模块名取别名

2.2 from  ... import  ...

#两种方式
1.from md1 import money,read1 #从md1模块拿出变量名或者函数名,可以导出封装的私有属性
 2.from dir1.dir import m1  # 从dir1文件中的dir文件里取出m1模块

#导入过程    
1.会先创建run1.py的名称空间
2.首次导入md1.py模块
    1.运行md1.py,创建md1的名称空间
    2.将产生的名字存放到md1.py名称空间中
    3.执行文件直接拿到指向模块md1.py名称空间中某个值的名字 # 这一步与import导入不同
    
    
#缺点:(目前缺点,习惯就好)
        1.访问模块中的名字不需要加模块名前缀  
        2.在访问模块中的名字可能会与当前执行文件中的名字冲突(执行文件中一定不要用和模块中变量或者函数一样的名字)
        
# 一次取出多个变量或函数
1. from md1 import money,read1,read2,change
2.from md1 import *  # 一次性将md1模块中的名字全部加载过来 不推荐使用 名字太多时贼占内存
  *的实质:模块文件末尾有个__all__,不写默认全部拿出,写了只拿出你写的那部分,如拿出三个在模块中写: __all__ = ['money','read1','read2']或者拿一个__all__ = ['money']
  __all__后面支持函数或者变量等,支持公有属性和私有属性,即封装的也可以

2.3 循环导入(一般不会用 了解即可)

1.如果出现循环导入问题 那么一定是你的程序设计的不合理
  循环导入问题应该在程序设计阶段就应该避免

2.解决循环导入:
    1.方式1
        将循环导入的句式写在文件最下方() #这样一来各个文件中变量都定义完毕都能找到,如果放在中间,变量在循环句式下方定义,找变量的时候就找不到会报错
    
    2.方式2
        函数内导入模块

 

 

 三、模块的查找顺序

#模块的查找顺序
1.先从内存中找
2.内置中找
3.sys.path中找(环境变量):是一个大列表,里面放了一对文件路径,第一个路径永远是执行文件所在的文件夹,可以往该列表中添加路经

#往环境变量中添加路经 当执行文件和md模块(dir1文件下dir文件中)不在一个目录下时:
import md 直接调用会出错 第一种方法: import sys sys.path.append(r'D:\Python项目\day14\dir1') #往大列表中添加md所在的文件夹路经 from dir import md #此时就可以找到dir文件再找到md模块 第二种方法: from dir1.dir import md #直接指定路径 #说明先找内存 import time import md time.sleep(20) #先调用md模块文件,然后将其加载读到内存创建md的名称空间,这时候让系统睡20s, # 期间把md文件删除,但是睡醒后还能继续往下运行至结束,执行完毕内存会立马释放名称空间,再次调用就会报错, # 说明先找的是内存 md.f1() #验证再找内置 import time print(name) #新写一个time模块,保证内存中没有,然后运行发现什么也没有输出,说明找的是内置不是路经下的 print(time.name)#我们调用内置的time模块方法能输出时间戳说明找到的就是内置

四、模块的绝对和相对导入

#引子
执行文件和模块m1、m2不在一个文件夹下,m1和m2在一起,m1调用m2
import m2  # 报错 找路经的时候是站在执行文件的立场上,即使模块m1和m2在一个文件中,m1调m2也不能直接找到
from dir1.dir import m2  #绝对路径找,正确
from . import m2  # 相对路径找,正确

#绝对导入(常用,结构清晰)
必须依据执行文件所在的文件夹路径为准,无论在执行文件中还是模块中都适用
      
#相对导入(执行文件中不能用)
    .代表的当前路径
    ..代表的上一级路径
    ...代表的是上上一级路径

注意相对导入不能在执行文件中使用,相对导入只能在被导入的模块中使用,使用相对导入 ,就不需要考虑执行文件到底是谁,只需要知道模块与模块之间路径关系

 五、包

5.1  什么是包?

 1.它是一系列模块文件的结合体,表示形式就是一个文件夹,本质还是一个模块
 2.包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来

5.2.python2和python3的不同(补充知识)

                  python2如果要导入包 包下面必须要有__init__.py文件
                  python3如果要导入包 包下面没有__init__.py文件也不会报错
                  当你在删程序不必要的文件的时候 千万不要随意删除__init__.py文件

5.3首次导入包名称空间创建:


              先产生一个执行文件的名称空间
              1.创建包下面的__init__.py文件的名称空间(运行包首先会立马运行_init_文件,因此把其他小包路径都放在这里)
              2.执行包下面的__init__.py文件中的代码 将产生的名字放入包下面的__init__.py文件名称空间中
              3.在执行文件中拿到一个指向包下面的__init__.py文件名称空间的名字
                ps:在导入语句中 .号的左边肯定是一个包(文件夹)

5.4 作为包的设计者:
          1.当模块的功能特别多的情况下 应该分文件管理
          2.每个模块之间为了避免后期模块改名的问题 你可以使用相对导入(包里面的文件都应该是被导入的模块)
            ps:创建包的目的不是为了运行,而是被导入使用,不用担心相对导入后就不能执行了
          3.如果使用绝对路径来管理的自己的模块 那么它只需要永远以包的路径为基准依次导入模块
      站在包的使用者:
          如果包和执行文件不是同级文件夹,例如本来执行文件和包p文件夹同级,用户把包放在了与执行文件同级的的outter文件夹下
          就必须得将包所在的那个文件夹(outter文件夹)路径添加到system path中,无论使用相对导入还是绝对导入都避免不了这个问题(******)

绝对导入和相对导入(执行文件和包顶级文件P同级情况下)

 

 


 






posted @ 2019-07-16 16:36  www.pu  Views(335)  Comments(0Edit  收藏  举报