模块基础——模块简介、模块导入方式、模块查找顺序

文章目录

      • 模块简介
      • 模块的使用
        • import句式
        • from...import...句式
        • 模块的补充知识
        • 判断文件类型
        • 循环导入问题
        • 模块的查找顺序(重点)
      • 面向过程编程
        • 面向过程的优缺点

模块简介

  • 什么是模块?

    模块就是一系列功能的集合。在python中,一个py文件就是一个模块,文件名为mytest.py,则模块名为mytest,导入模块就可以引用模块中已经写好的功能和变量。

  • 为什么要使用模块?

    使用模块的目的是为了提高开发效率,站在巨人的肩膀上进行开发,保证了代码的重用性,又增加了程序的可维护性。

  • 模块的分类?

    1. 内置模块:在python解释器中已经存在的,例如time模块等。
    2. 第三方模块:别人已经写到的功能,并且在网上公开给其他开发者使用的。
    3. 自定义模块:就是自己写的,自己来用的模块。
  • 模块的表现形式?

    1. 使用python编写的代码(.py文件),一个py文件就是一个模块。
    2. 已经被编译为共享库或者DLL的C或C++扩展。
    3. 包含多个py文件的文件夹叫作包,包也是模块。
    4. 使用C编写并链接到python解释器的内置模块。

模块的使用

​ 使用模块的目的是为了提高开发的效率,那么我们该如何导入模块来供我们使用呢?下面介绍模块的导入方式。

import句式

​ 通过import加模块名,则表示对模块的导入。

有如下代码文件:

# test1.py  导入文件
num = 100
def get_num():
    print(x)
    
def change():
    global num
    num = 0

# start.py  执行文件
# 在学习模块的时候,首先分清楚谁是执行文件,谁是导入文件
import test1  # 导入的模块test1,注意不要加后缀

num = 200
x = test1.num  # 引用模块test1中num的值赋值给当前名称空间中的变量x
print(x)
test1.get_num()  # 调用模块test1中的get_num()函数
test1.change()  # 调用模块test1中的change()函数
  • 模块被导入时注意:

    模块会执行,但是导入多次,只会执行一次。

  • 模块首次导入时发生了哪些事?

    1. 运行执行文件,产生一个执行文件的全局名称空间。
    2. 运行被导入文件,产生一个模块的全局名称空间。
    3. 模块中的名字放入到模块的名称空间中。
    4. 在执行文件的名称空间中有一个test1的名称指向模块的名称空间。

    图解:
    模块基础——模块简介、模块导入方式、模块查找顺序_第1张图片

    注意:在start.py的名称空间中有与test1.py的名称空间中有相同的名字,但是在使用模块名称空间中的名字时,会通过test1.加名字来引用,所以不会出现名称冲突的问题。

from…import…句式

​ from…import…与import语句基本一致,唯一不同的是:使用import test1导入模块后,引用模块中的名字都需要加上test1.作为前缀,而使用from test1 import num,get_num,change来导入,start则可以在当前执行文件中直接引用模块test1中的名字,如下代码所示:

from test1 import num
from test1 import get_num,change

print(num)
get_num()
change()
  • 使用from…import…导入模块时注意:

    文件作为模块被导入时,模块文件会执行。

  • from…import句式首次被导入时发生了什么?

    1. 产生一个执行文件的名称空间。
    2. 运行导入文件。
    3. 产生一个导入文件的名称空间。
    4. 在执行文件中产生num,get_num, change,执行导入文件中的相应变量。导入文件中的名称若没有被导入,在执行文件中就无法使用,若要使用,则必须再次导入该名称。
  • 连续导入:

    from test1 import num,get_num,change

模块的补充知识

  • 使用as来起别名

    as既可以给模块起别名,也可以给模块中的某一个名字其别名

    示例:

    # my_first_model.py
    num = 100
    def get_num():
        print(x)
        
    def change():
        global num
        num = 0
        
    # start.py
    import my_first_model as model
    print(model.num)
    model.get_num()
    model.change()
    
    from test1 import num as a
    print(a)
    
  • 连续导入

    可以一个句式导入多个模块,每个模块之间用逗号隔开。

    示例:

    # 方式一:
    import time
    import os
    import sys
    
    # 方式二:
    import time,os,sys
    
  • 通用导入

    在使用from…import…句式时,可以使用*号来表示导入模块中的所有名称。

from test1 import *

print(num)
get_num()
change()

注意:模块的编写者可以通过在自己的文件中定义__all__变量来控制*号代表的意思。

# first.py
num = 100
def get_num():
    print(x)
    
def change():
    global num
    num = 0
__all__ = ['num','get_num']   



# start.py
from first import *
print(num)  # 可用
get_num() # 可用
change()  # 不可用

判断文件类型

​ 因为一个python文件,可以是执行文件,也可以是被导入文件,那么我们该如何来区分呢?python中通过__name__的内容来进行区分。

​ 注意:

​ 如果在执行文件中,__name__的值是__main__,并且是字符串类型。

​ 如果作为模块时,__name__的值被赋予模块名。

作为模块的开发者,可以在文件末尾基于__name__在不同应用场景下的值的不同来控制文件执行不同的逻辑。

# test.py
if __name__ == '__main__':
    test.py被当做脚本执行时运行的代码
else:
    test.py被当做模块导入时运行的代码

循环导入问题

​ 循环导入指的是在一个模块导入的过程中导入另外一个模块,而在另外一个模块中又返回来导入第一个模块中的名字,由于第一个模块尚未加载完毕,所以引用失败、抛出异常,究其根源就是在python中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会去重复执行内部代码。我们从以下例子来做出分析:

# m1.py
print('正在导入m1')
from m2 import y

x='m1'

# m2.py
print('正在导入m2')
from m1 import x

y='m2'

# start.py
import m1

运行start.py:
模块基础——模块简介、模块导入方式、模块查找顺序_第2张图片
分析:

​ 先执行start.py,执行import m1,开始导入m1,并运行其内部代码,打印内容"正在导入m1",然后执行from m2 import y 开始导入m2并运行其内部代码,打印内容“正在导入m2”,再执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错。

解决方案:在文件的最后导入模块

# m1.py
print('正在导入m1')

x='m1'
from m2 import y

# m2.py
print('正在导入m2')

y='m2'
from m1 import x

# start.py
import m1

结论:

​ 循环导入问题是不允许出现的,如果出现,则是程序设计不合理。

模块的查找顺序(重点)

  1. 先从内存中查找
  2. 再从内置中查找
  3. 最后从sys.path,按照从左到右的顺序,依次查找。

如果在你的执行文件中找不到模块的时候,解决方案:把模块所在的路径加到sys.path中。

面向过程编程

​ 面向过程编程, 核心是”过程“二字,即先干什么,在干什么,最后干什么,表示一件事的执行步骤。面向过程编程不是一门技术,而是一种思想。

举例:把大象放冰箱分几步?

  1. 打开冰箱门
  2. 把大象塞进去
  3. 把冰箱门关上

面向过程的优缺点

  • 优点:使复杂的问题简单化

  • 缺点:扩展性差

  • 使用场景:在对扩展性要求不高的项目中可以使用面向过程的思想。

你可能感兴趣的:(python基础,python,pycharm,开发语言)