模块与包
【一】什么是模块
- 在Python中,一个 py文件就是一个模块
- 文件名 xx.py xx就是模块名
- 编写模块的过程就是将零件拼装成一个完整的部件
- 利用框架将所有部件拼接成一个完整的机器
用模块开发代码,将某部分代码分别放到一个py文件中
再利用主函数进行整合--->三层架构
- 总(分析功能,分配功能)
- 分(给每个文分配任务)
- 总(将写好的功能总结到一个入口处)
【二】模块的优点
- 增加程序的健壮性和可读性
- 大大增加开发效率
- 锻炼自己的逻辑思维
【三】模块的来源
python解释器内置有很多模块
自己写的文件也是一个模块
别人写好的 用 pip install 下载的
【四】模块的存在形式
【1】单模块
自己定义的功能所在的py文件
【2】包
将自己定义的功能所在的py文件总结起来,放到一个文件夹下构成一个包
必须有__init__.py文件
模块使用
settings.py
# Author : wh
# Time : 2024/4/18
# 定义变量name
name = 'qwer'
# 定义函数,打印变量name
def outer():
print(name)
# 定义函数修改变量name
def outer_change():
global name
name = '123'
print(name)
# 内嵌函数
def outer_():
def inner():
print("outer_内部inner")
return inner
【一】使用模块中的属性
# 导入模块
import settings
# 打印模块对象地址
print(settings)
# 打印模块中name值
print(settings.name)
# 调用模块中outer()函数
settings.outer()
# 调用模块中outer_change()并打印他的函数返回值
print(settings.outer_change())
# 打印模块中name值
print(settings.name)
# 调用outer_()
settings.outer_()
#调用内嵌函数
func = settings.outer_()
func()
输出
<module 'settings' from 'D:\\pythonProject\\day17\\settings.py'>
qwer
qwer
123
12312313
123
outer_内部inner
【二】import语句发生的内部原理
前提是有一个自己写的py文件 在这个文件内部有自己的名称空间
通过import导入模块
进入py文件,将所有源代码执行一遍
-
例子
-
settings.py中 一个输出,两个函数,但是只调用了一个函数
-
# 定义变量name name = 'qwer' print(name) # 定义函数,打印变量name def outer(): print(name) # 定义函数修改变量name def outer_change(): global name name = '123' print(name) return 12312313 outer_change()
-
-
引用中只写一行代码 import settings
-
import settings 输出 qwer 123
-
-
如果没有调用函数则不会调用而是检索到所有的函数地址
检索完后会自动创建一个当前文件的名称空间,将py文件的名称空间和自己的名称空间合并
![屏幕截图 2024-04-18 153503](C:\Users\jy255\Pictures\Screenshots\屏幕截图 2024-04-18 153503.png)
通过模块名.属性名来调用
【三】支持导入多个模块
【1】单独导入多个模块
import settings
import time
import this
。。。
【2】一次性导入多个模块
import settings,time,this...
【四】详细导入语法
# from 模块名 import 属性名
【1】想要模块中的指定语法
比如只想使用settings中的outer_
使用from语法
from settings import outer_
【2】想要模块中的所有参数和方法
from settings import *
导入后不必使用模块名.属性名来调用
只需直接调用即可
outer_change()
qwer
123
【五】重命名模块
若是引用文件中有与导入模块重名的函数
则会将导入函数的名称空间冲掉
(未重名)
import settings
print(settings)
输出
<module 'settings' from 'D:\\pythonProject\\day17\\settings.py'>
(重名)
import settings
settings = {'1':'2'}
print(settings)
输出
{'1': '2'}
重命名
import settings as a
print(a)
settings = {'1':'2'}
print(settings)
<module 'settings' from 'D:\\pythonProject\\day17\\settings.py'>
{'1': '2'}
循环导入问题
- 在一个文件中调用了另一个文件
- 另一个文件在调用当前文件
【1】问题来源
- bar.py
print('正在导入foo')
from foo import name_foo
name_bar = 'bar'
- foo.py
print('正在导入bar')
from bar import name_bar
name_foo = 'foo'
- main.py
# import foo
import bar
# (most likely due to a circular import)
【2】解决办法
(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 foo
import bar
# 导入foo 开始
# 导入bar 开始
# 导入bar 结束
# 导入foo 结束
(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 install )
- 纯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)
# ['D:\\pythonProject\\day17', 'D:\\pythonProject\\day17', 'D:\\pycharm\\PyCharm 2023.2.1\\plugins\\python\\helpers\\pycharm_display', 'D:\\python310\\python310.zip', 'D:\\python310\\DLLs', 'D:\\python310\\lib', 'D:\\python310', 'D:\\python310\\lib\\site-packages', 'D:\\pycharm\\PyCharm 2023.2.1\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
包
【一】什么是包
- 模块是功能的集合体,将开发的当前模块的所有功能都梵高了一个模块中
- 将模块统一成一个文件夹,从这个文件夹中导入指定的功能即可
- 包就是模块的集合体
【二】如何创建包
# 【1】创建一个文件夹
# 在文件夹内部创建 一个 __init__.py 文件
# 这个文件夹就叫包
# 【2】在pycharm右键文件新建 package
# 自动创建 __init__.py 文件
【三】使用包
(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 'D:\\Python\\PythonProjects\\PythonProjects29\\day17\\calculator\\add.py'>
print(add.add('1','2')) # 这里的 add 是模块名
(2)方式二
__init__.py
# 符合初始化当前包的民称空间
# 如果不在这里注册 就只能导入 模块名
# 前面要加. 表示当前路径
from .add import add
from .multy import multy
- main.py
from calculator import add,multy
# print(add) # <function add at 0x000001764FC3C8B0>
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强转,转换后的字符串无法转回去
【2】什么是反序列化
将字符串类型的数据转换为Python对象(字典、列表、元组等)
【3】json模块
(1)导入
import json
(2)保存和读取
序列化保存Python对象数据
user_data_dict = {
'username': "dream",
"password": "521"
}
# 存储为json文件数据
with open('user_data.json', 'w', encoding="utf-8") as fp:
json.dump(obj=user_data_dict, fp=fp)
反序列化转换Python对象数据
with open('user_data.json', 'r', encoding="utf-8") as fp:
data = json.load(fp=fp)
print(data, type(data))
【4】转换
# 反序列化和序列化方法之转换
# 我就想将一个字典转换为字符串 转回字典
# (1)将字典转换为字符串格式
data_json_str = json.dumps(obj=user_data_dict)
print(data_json_str, type(data_json_str)) # {"username": "dream", "password": "521"} <class 'str'>
# (2)将字符串转回 python对象
data_json_dict = json.loads(data_json_str)
print(data_json_dict, type(data_json_dict)) # {'username': 'dream', 'password': '521'} <class 'dict'>
【5】保存中文数据
user_data = {'name': "王", "age": 22}
with open('data.json', 'w', encoding='utf-8') as fp:
json.dump(obj=user_data, fp=fp, ensure_ascii=False)
# 编码和解码
# 编码 encode(编码格式)
# 解码 decode(编码格式)
标签:bar,name,py,模块,print,import
From: https://www.cnblogs.com/yi416/p/18206501