初识模块

1.1 模块

1.1.1 模块介绍

常见的场景:一个模块就是一个包含了一组功能的python文件,比如module.py,模块名为module,可以通过import module使用。

模块的三种来源:

1.内置的(python解释器自带的)
2.第三方的(别人写的)
3.自定义的(自己写的)

 

模块可以分为四个通用类别: 

1.使用python编写的py文件(也就意味着py文件也可以称之为模块:一个py文件也可以称之为一个模块)
2.已被编译为共享库或DLL的C或C++扩展(了解)
3.把一系列模块组织到一起的文件夹(文件夹下有一个__init__.py文件,该文件夹称之为包)
包:一系列py文件的结合体
4.使用C编写并连接到python解释器的内置模块

 

1.1.2 为何要使用模块

1、从文件级别组织程序,更方便管理

随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用

2、拿来主义,提升开发效率

同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率

 

如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行

#ps:一定要分清楚谁是执行文件谁是被导入文件

 sys.path是一个大列表,里面放了一堆文件路径,第一个永远是执行文件所在的文件夹


1.2 使用模块之import

1.2.1 import的使用

模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下

#run.py

 

 

 

1.2.2 在第一次导入模块时会做三件事,重复导入会直接引用内存中已经加载好的结果

1.为源文件(module模块)创建新的名称空间,在spam中定义的函数和方法若是使用到了global时访问的就是这个名称空间。

2.在新创建的命名空间中执行模块中包含的代码,见初始导入import module

 提示:导入模块时到底执行了什么?

事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放入模块全局名称空间表,用globals()可以查看

3.创建名字module来引用该命名空间

    这个名字和变量名没什么区别,都是‘第一类的’,且使用module.名字的方式

    可以访问module.py文件中定义的名字,module.名字与test.py中的名字来自

    两个完全不同的地方。

1.2.3 被导入模块有独立的名称空间

每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突

 

 

1.2.4 为模块名起别名

当模块名字比较复杂的情况下 可以为该函数起别名  如下列情况:

 

 

用 as t 为这个不知道有多少个t的文件取个别名

t . 方法还是能够取到testtttttttttttttt.py文件中的值

 

1.2.5 在一行导入多个模块

import os,time,module(不推荐使用)

特例:

只有当几个模块有相同部分或者属于同一个模块,可以使用上面的方法
当几个模块没有联系的情况下 应该分多次导入
import os
import time
import module
ps:通常导入模块的句式会写在文件的开头

 

1.2.6 使用模块之from ... import...

1.2.6.1  from ... import... .的使用

#md1.py

#run1.py文件执行结果:

 


1.2.7 from...import 与import的对比

唯一的区别就是:使用from...import...则是将spam中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接使用名字就可以了、无需加前缀:module.

#from...import...的方式有好处也有坏处

    好处:使用起来方便了

    坏处:容易与当前执行文件中的名字冲突

 

1.2.8 from module import *

#from module import * 一次性把module模块中的名字都加载过来

 

#大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。

#ps: __all__ 方法可以规定导入的数量
如:  __all__ = ['money','read1','read2']

 

 

1.3 循环导入问题及解决思路

 

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

解决循环导入问题的方式
1.方式1
将循环导入的句写在载文件最下方()
2.方式2
定义一个函数 函数内导入模块

1.4 py文件区分两种用途:模块与脚本

写好的一个python文件可以有两种用途:

    一:脚本,一个文件就是整个程序,用来被执行

    二:模块,文件中存放着一堆功能,用来被导入使用

 

#python为我们内置了全局变量__name__,

    当文件被当做脚本执行时:__name__ 等于'__main__'

    当文件被当做模块导入时:__name__等于模块名

 

#作用:用来控制.py文件在不同的应用场景下执行不同的逻辑

    if __name__ == '__main__':

 

 

1.5 模块搜索路径

模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

模块的查找顺序

1、在第一次导入某个模块时(比如module),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用

    ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看

2、如果没有,解释器则会查找同名的内建模块

3、如果还没有找到就从sys.path给出的目录列表中依次寻找module.py文件。

 

 

1.6 绝对导入和相对导入

绝对导入:必须依据执行文件所在的文件夹路径为准

     绝对导入无论在执行文件中还是被导入文件都适用

相对导入:用.或者..的方式最为起始

1.6.1 绝对导入

 

 

1.6.2 相对导入

.代表的当前路径
..代表的上一级路径
...代表的是上上一级路径

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

1.7 软件开发规范

                        

 

posted @ 2019-07-16 21:12  Zeus-Lin  阅读(177)  评论(0编辑  收藏  举报