【一】模块与包介绍
【1】什么是模块
在Python中,一个py文件其实就是一个模块
文件名 knight.py中 py就是模块名
【2】模块的优点
有了模块以后可以增加程序的可读性,提高开发效率
【3】模块的来源
(1)在Python解释器内部内置有很多模块
(2)自己写的文件也是一个模块
【4】模块的存在形式
(1)单模块
就是自己定义的功能所在的py文件
(2)包
将自己定义的功能所在的py文件总结起来,放到一个文件夹下,构成一个包
必须有--init--.py文件
【二】模块的使用
# knight文件 name = "knight" # 定义一个函数 函数的功能是打印name def show_name(): print(name) # 定义一个函数修改name def change_name(): global name name = "hyt" # print(name) # 内嵌函数 def outer(): def inner(): print(f'这是outer内部的inner') return inner
下面我又新建了一个文件,在新建文件中 ,导入上面的模块文件knight
import knight # 打印当前 模块对象 位置 print(knight) # 打印模块中的 name 值 print(knight.name) # 调用模块中的更改name值的方法 修改全局的name knight.change_name() # 更新全局的name print(knight.name) # 调用内嵌函数 func = knight.outer() func()
【2】import语句发生的内部原理
前提是有一个自己写的 xxx.py 文件 在这个py文件内部有自己的名称空间
通过import xxx 导入了当前模块
进入到xxx.py 文件,将所有源代码执行一遍
如果没有写调用函数的命令,则不会调用,而是检索到所有的函数地址
会自动创建一个xxx.py文件的名称空间 --->将xxx.py 文件 的名称空间和 自己的名称空间合并
通过模块名.属性名
【3】支持导入多个模块
(1)方式一:单独导入多个模块
import knight import time import user_src
(2)方式二:一次性导入多个模块
import knight, user_src, time
【4】详细导入语法
(1)只要模块中的指定参数或者方法
from 模块名 import 属性名 from knight import show_name show_name()
(2)只要模块中的所有参数和方法
from knight import * show_name() print(name) outer = outer() outer()
【5】重命名模块
对导入的模块进行重命名
import numpy as np # 导入模块 模块名叫 knight,但我改成gdy from knight import name as gdy # 在当前文件中执行gdy print(gdy) # knight
【三】循环导入问题
在一个文件中调用另一个文件
另一个文件再调用当前文件
【1】方法一
bar.py
print("正在导入foo") name_bar = 'bar' from foo import name_foo print('导入foo结束')
foo.py
print('正在导入bar') name_foo = 'foo' from bar import name_bar print('导入bar结束')
main.py
import bar
【2】方法二
foo.py
print('导入bar开始') name_foo = 'foo' def show_name_foo(): from bar import name_bar print(name_bar) print('导入bar结束')
bar.py
print('导入foo开始') name_bar = 'bar' def show_name_bar(): from foo import name_foo print(name_foo) print('导入foo结束')
main.py
import bar bar.show_name_bar()
【四】模块加载和搜索顺序
【1】模块的分类
纯python编写的自己定义的模块
内置的一系列模块 (python解释器自带的和你安装 pip install )
使用c语言编写的底层代码
c 和 c++ 扩展出去的模块
【2】加载顺序
先c 和 c++ 扩展出去的模块
使用c语言编写的底层代码
内置的一系列模块 (python解释器自带的和自己安装的pip)
自己编写的定义的Python文件
【3】查找顺序
先从自己的局部查
def func(): import time
再从全局查
import time
再去内建查
python解释器自带的模块和你安装的模块中查,查出对应的模块再使用
去底层c语言查
有些功能点进去看源码发现只有一个pass,是因为它使用c语言写的,但是被他省略了
【五】绝对路径和相对路径
【1】相对路径
# ./表示当前同级目录下 # ../表示当前目录的上一级目录 # 默认就是当前目录下 with open('../user_data.text', 'w', encoding='utf-8') as fp: fp.write('111'
【2】绝对路径
# 在python内部查找的顺序都是绝对 import sys print(sys.path) # [ # 'H:\\pycharm projects\\day\\模块学习', # 'H:\\pycharm projects', # 'H:\\Pycharm\\PyCharm 2023.3.5\\plugins\\python\\helpers\\pycharm_display', # 'H:\\python\\python310.zip', # 'H:\\python\\DLLs', # 这里放的就是c语言源码编译后的扩展包 # 'H:\\python\\lib', # 放的是内置的模块或者安装的模块 # 'H:\\python', # # 安装python解释器的路径 # 'H:\\python\\lib\\site-packages', # 这里面也有部分安装的的包 ,默认安装到 site-packages # 'H:\\Pycharm\\PyCharm 2023.3.5\\plugins\\python\\helpers\\pycharm_matplotlib_backend' # ]
【六】包
【1】什么是包
模块是功能和集合体,将开发的当前模块的所有功能都放到了一个 模块中
例如:加(逻辑验证) 减(逻辑验证) 乘(逻辑验证) 除(逻辑验证)
将上述四个模块统一成一个文件夹,从这个文件夹中导入指定的功能即可
包就是模块的几何体
【2】如何创建包
# 【1】创建一个文件夹 # 在文件夹内部创建一个__init__.py文件 # 这个文件就叫包 # 【2】在pycharm右键文件新建package # 自动创建__init__.py文件
【3】使用包
(1)方式一
__init__.py
# 这个文件是空白
add.py
def add(x, y): print("加法功能") if not x.isdigit() or not y.isdigit(): return False, f'当前数字格式错误' return True, int(x) + int(y)
multy.py
def multy(x, y): print(f"乘法功能") if not x.isdigit() or not y.isdigit(): return False, f'当前数字格式错误' return True, int(x) * int(y)
main.py
from calculator import add,multy # <module 'calculator.add' from print(add.add('1','2'))
(2)方式二
__init__.py
# 在这个文件中注册,如果不在这注册就只能和上面一样导入模块名 from .add import add from .multy import multy
main.py
from calculator import add,multy x = '2' y = '9' print(add(x, y)) # 这里的add是方法名 print(multy(x, y)) # 这里的add是方法名
【七】导入语法总结
# import 模块名 语法 只会检索当前模块内的所有变量名 # import 包名 语法 会自动检索 __init__.py文件内的所有变量名,然后再去检索每一个模块的里面的变量名 # 加载的时候多加载一层__init__.py # 查找的时间也多查找一层__init__.py # 不管是在模块还是包还是自己文件中,只要检索到指定名字就好停止检索
【八】json模块
【1】什么是序列化
将Python中的字典、列表、元组 ... 转换成 字符串类型
如果使用str强制转换数据类型,造成的后果就是转换后的字符串无法转回Python对象
【2】什么是反序列化
将字符串类型的数据转换成Python对象(列表、字典、元组 ... )
能将python对象转为字符串 --> 字符串转回python对象
【3】json模块
(1)导入json模块
import json
(2)保存和读取
[1] 序列化保存Python对象数据
json.dump()保存py数据到json文件中
import json user_data_dict = { 'username': "knight", "password": "123" } # 保存到本地文件中,保存进去的是字典格式,文件格式为json数据 with open("user_data.json", "w", encoding="utf-8") as file: json.dump(obj=user_data_dict, fp=file) # {"username": "knight", "password": "123"} # 在内部自动将单引号全部转换为双引号
[2] 将json格式数据转换为Python对象数据
json.load()转换为Python数据
with open("user_data.json",'r',encoding="utf-8") as file: data = json.load(file) print(data,type(data)) #{'username': 'knight', 'password': '123'} <class 'dict'>
(3)转换
# 反序列化和序列化方法转换 # 将一个字典转换为字符串 再转回字典
[1] 将字典转换为字符串格式
data_json_str = json.dumps(obj=user_data_dict) print(data_json_str, type(data_json_str)) # {"username": "knight", "password": "123"} <class 'str'>
[2] 将字符串转换为字典
data_json_dict = json.loads(data_json_str) print(data_json_dict, type(data_json_dict)) # {'username': 'knight', 'password': '123'} <class 'dict'>
(4)保存中文数据
user_data = {'name': "爱意", "age": 18} with open('data.json', 'w', encoding='utf8') as fp: json.dump(obj=user_data, fp=fp, ensure_ascii=False) # 编码和解码 # 编码 encode(编码格式) # 解码 decode(编码格式)