模块

发布时间 2023-06-06 17:14:02作者: Meeeoww

模块的简介

1. 什么是模块?
	内部具有一定功能的模块(py文件),可以直接使用,模块就是一个工具包,要想使用这个工具包就得导入这个模块
2. 为什么要用模块?
	拿来主义,极大地提高了开发效率
3. 模块的分类
	1. 内置的:# python解释器自带的,直接拿来使用的eg time模块
    2. 第三方的 # 别人写的模块文件,如果想用,就要先下载在使用
    3. 自定义的 # 我们自己写的模块文件
4. 模块的存在形式
	1. 我们自己写的py文件(一个py文件就是一个模块)
    2. 包:一系列py模块的集合体(模块通俗就是文件夹)
    	# 一个包里面会有一个__init__.py文件

5. 导入模块的两种句式
	import句式
	from...import...句式

import句式

# 在学习模块的时候,要区分谁是执行文件,谁是导入文件

import md  # 导入模块的时候,文件名.py\.txt后缀不能加

""" 
 import句式可以通过句点符的形式找到导入文件中得名字
	底层原理:
	    1. 运行执行文件,产生执行文件的全局名称空间
	    2. 运行导入模块文件(md.py),导入模块文件此时就会产生一个 模块文件的名称空间
	    3. 在执行文件中有个变量(import md),(md)指向导入文件的名称空间所有名字
	    4. 通过这个名字以模块名.的方式就可以使用模块空间中的对应的名字的数据   
  
"""
导入文件md.py内容如下:
print('from the md.py')
money=1000
def read1():
    print('md',money)
def read2():
    print('md模块')
    read1()
def change():
    global money 
    money =0

执行文件内容如下:
import md#导入模块md.py
import md
import md
import md#只执行首次导入,之后导入的不执行
money =666
print(md.money) #相当于指名道姓导入模块中md.money的值
>>>from the md.py
1000  
  • 例1
import md
def read1(): #没有被调用不会打印
    print('from read1')
md.read2()#导入模块中read2也调用了read1值
>>>from the md.py
md模块
md 1000
  • 例2
import md
def read1():
    print('from read1')
md.read2()
read1() #调用read1会被打印
>>>from the md.py
md模块
md 1000
from read1
  • 例3
import md
def read1():
    print('from read1')
md.read2() #调用导入模块中的read2
md.read1() #调用导入模块中的read1
>>>from the md.py
md模块
md 1000
md 1000
  • 例4
import md
money =999#当执行文件与导入文件同名时,默认执行当前执行文件中的
md.change()
print(money)
>>>from the md.py
999

from...import...句式

from md import money
from md import money
from md import money
from md import money
>>>from the md.py#与import一样只执行首次导入,之后导入的不执行

"""
    from...import..是指名道姓的导入
	当导入文件中存在money,如果执行文件中也存在money,此时就会产生冲突,就会使用当前执行文件中的名字
	
	底层原理
    1. 运行执行文件,产生执行文件的全局名称空间
    2. 运行导入md.py文件,产生md文件的全局名称空间,然后把md中所有的名字丢到md的名称空间中
    3. 在执行文件中有个变量(from md import money),指向导入文件money的名称空间
    4. 执行文件中直接使用名字就可以访问名称空间的对应名字(不用使用句点符的方式访问)   

""" 
导入文件md.py内容如下:
print('from the md.py')
money=1000
def read1():
    print('md',money)
def read2():
    print('md模块')
    read1()
def change():
    global money
    money =0

执行文件内容如下:
from md import money
money = 666
print(money)
>>666
  • 例1
money = 666
from md import money#注意导入顺序
print(money)
>>1000

导入模块的补充

  • 两种句式的对比
1.import句式 使用模块名称空间的名字需要用模块名点的方式,所以不会与执行文件中名字起冲突
2.from...import...句式 使用指名道姓的方式导入模块名称空间的名字,不需要模块名点的名字,容易与执行文件中的名字起冲突
  • 起别名
1.1给模块名起别名
#import 旧名 as 新名
import mddddddddddddddd as md1#mddddddddddddddd为导入模块名,md1为新起名
print(md1.mame)#起别名后旧名就不能用


1.2给模块中名字起别名
导入文件mddddddddddddddd内容如下:
mameeeeeee ='md.py' 
当导入的文件内容文件名要修改时#from 文件名 import 旧名 as 新名
from mddddddddddddddd import mameeeeeee as name
print(name)
>>md.py
  • 连续导入
import time
import md
import os
import sys

import time, md, os, sys # 等价于上面4行代码
import 模块名1, 模块名2, 模块名3, 模块名4, 模块名5/from md import 模块名1, 模块名2, 模块名3
    # 推荐还是分开导入
  • 通用导入
from md import * #*代表md中所有的名字
print(money)
print(read1())
print(read2())
#导入文件中的文件名要手动添加
  • __all__的使用
#在被导入文件中限制当前文件中可导入使用的名字:
__all__=['money','read1']#列表内必须是字符串类型且要配合from md import *使用,不能用于import句式

判断文件类型

"""
所有的py文件都可以直接打印__name__对应的值
在执行文件中打印,结果是 __main__(str类型)
在导入文件中打印,结果是:模块名
"""

# 判断当前文件是执行文件还是导入文件
print(__name__)
print(type(__name__))
>>__main__   #在执行文件中,结果是 __main__
<class 'str'>

import mddddddddddddddd
>>mddddddddddddddd #在导入文件中,结果是:模块名
<class 'str'>
if __name__ == '__main__': #快捷键直接输入main
    print('当前是执行文件')
上述脚本可以用来区分所在py文件代码的执行  
上述脚本使用场景
1.模块开发阶段
2.项目启动文件

* 例
def eat():
    print('想干饭了')
   
def drink():
    print('想喝水了')
if __name__ = '__main__':
    eat()
    drink()
# 只有该文件是执行文件时,才会调用eat()、drink()两个函数,如果该文件是被导入文件时,不会执行

循环导入

循环导入就是两个文件间互相导入,并且使用到对方名称空间中的名字
#m1.py:
import m2
name='m1'
print(m2.name)
#m2.py:
import m1
name='m2'
print(m1.name)
"""报错:most likely due to a circular import,上述情况为循环导入"""
  • 出现循环导入如何解决
在导入之前确保名字已经加载出来了,也就是导入模块的代码放在名字代码的后面
name='m2'
import m1
print(m1.name)

模块的查找顺序

查找顺序:
	1. 首先从内存中查找
	2. 再从内置模块中查找 # 文件名命名坚决不能跟内置模块名重名 
	3. 再从执行文件所在的环境变量中查找sys.path 
		#sys.path中的第一个元素的路径永远都是当前文件所在位置
		#sys.path中的第二个元素的路径是项目路径,是pycharm加的
  • 从内存中查找
#导入文件m3.py
name=123
#执行文件
import m3
import time
time.sleep(10)
print(m3.name)#123
在time.sleep停顿中我们把m3.py文件从硬盘中删除后发现依然可以输出结果,因为是m3.py文件是先加载在内存中,说明模块查找先从内存中查找
第二次再执行上述代码就不能输出,因为硬盘中m3.py已经不存在了,没办法在加载到内存中
  • 从内置模块中查找
#导入文件time.py
time='123'
#执行文件
import time
print(time)#<module 'time' (built-in)>输出为内置模块time
print(time.time())#1686037867.1050787,再次验证为内置模块time,而不是我们手写的time.py
  • 环境变量中查找sys.path
import sys
print(sys.path)
# 返回路径,以列表形式
#sys.path中的第一个元素的路径永远都是当前文件所在位置
#sys.path中的第二个元素的路径是项目路径,是pycharm加的

  • 当查找模块找不到的时候,解决方法
方式一 把模块所在的文件夹根路径添加到环境变量中
import sys
sys.path.append(r'D:\python25\day18\aaaa')
print(sys.path)

方式二 使用绝对导入的方式导入模块
在导入与执行文件不在同一级别路径下的模块时可以使用句点符
from 模块名1.模块名2 import py文件