模块

1、什么是模块

常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

但其实import加载的模块分为四个通用类别: 

  1 自定义模块:使用python编写的代码(.py文件)

  2 第三方模块:已被编译为共享库或DLL的C或C++扩展

  3 包:包好一组模块的包

  4 python内置模块:使用C编写并链接到python解释器的内置模块

2、为什么使用模块

1、将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行

2、为了方便管理,我们通常将程序分成一个个的文件,除了当作脚本运行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用

3、如何使用模块

3.1 注意点

  • 为了防止对同一模块的重复导入,python的优化手段是:

    第一次导入后就将模块名加载到内存,以my_module为例

    后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句
    sys.modules中可以找到当前已经加载的模块

  • 每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间

3.2 首次导入模块时发生的事情

  • 为模块文件my_moudle.py创建新的名称空间
  • 在新创建的命名空间中执行模块中包含的代码
  • 用模块文件名my_moudle创建名字来引用该命名空间

3.3 import 模块名

3.3.1

添加了模块名称空间的引用,等同于将模块源文件的名称空间带到当前文件名称空间中,使用时必须是模块名.名字的方式

3.3.2

为模块名起别名,相当于m1=1;m2=m1

import my_module as sm
print(sm.money)

3.3.3

在一行导入多个模块

import sys,os,re

3.4 from ... import ...

3.4.1

  • from 语句相当于import,也会创建新的名称空间,但是将my_module中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了

    from my_module import read1,read2
    
  • 如果当前有重名read1或者read2,那么会有覆盖效果接使用read1read2就好了,执行时,仍然以my_module.py文件全局名称空间

3.4.2

也支持as

 from my_module import read1 as read

3.4.3

也支持导入多行

from my_module import read1,read2,money

3.4.4 from my_module import *

  • from my_module import * my_module中所有的不是以下划线(_)开头的名字都导入到当前位置

    因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字

    可读性极其的差,在交互式环境中导入时没有问题

  • my_module.py中新增一行,限制from my_module import * 能导入的名称

    __all__=['money','read1'] #这样在另外一个文件中用from my_module import *就只能能导入列表中规定的两个名字
    

3.4.5 循环导入

模块mim2相互导入

此时可能会出现一种情况:

m1m2导入的名称是在m2中的导入mi语句下面定义的

m2m1导入的名称是在m1中的导入m2语句下面定义的

因而m1m2中的导入语句都找不到目标名称,就像是陷入了循环一样,都不会执行下面的代码

解决办法

1、在import语句之前定义目标名称

2、在函数体内导入,因为函数只检测语法,不执行代码

3.4.6模块的加载与修改

  • 每个模块只被导入一次,放入字典sys.modules中,如果你改变了模块的内容,你必须重启程序,python不支持重新加载或卸载之前导入的模块
  • 删了sys.modules中的模块对象仍然可能被其他程序的组件所引用,因而不会被清除

3.5 把模块当作脚本运行

通过模块的全局变量__name__来查看模块名:

  • 当做脚本运行:__name__ 等于'__main__'
  • 当做模块导入:__name__= 模块名

作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if __name__ == '__main__':

3.6 模块搜索路径

内存中已经加载的模块->内置模块->sys.path路径中包含的模块

  • python解释器在启动时会自动加载一些模块,可以使用sys.modules查看

  • 在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载

    import sys
    sys.path.append('/a/b/c/d')
    sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
    

3.7 编译python文件

为了提高加载模块的速度,python解释器会在__pycache__目录中下缓存每个模块编译后的版本

python解释器在以下两种情况下不检测缓存:

  • 在命令行中被直接导入模块,每次导入都会重新编译,并且不会存储编译后的结果

    python -m my_module.py
    
  • 源文件不存在,那么缓存的结果也不会被使用,如果想在没有源文件的情况下来使用编译后的结果,则编译后的结果必须在源目录下

3.8 dir()函数

内建函数dir()是用来查找模块中定义的名字,返回一个有序字符串列表

import my_module
dir(my_module)
posted @ 2019-09-26 15:43  W文敏W  阅读(151)  评论(0编辑  收藏  举报