模块介绍,包,json模块

【一】模块

1.什么是模块

模块就是一系列功能的结合体,可以直接使用

2.为什么要模块

极大地提升开发效率

3.模块的三种来源

【1】内置模块

无需下载,解释器自带,直接导入使用即可

【2】自定义模块

自己写的代码,封装成模块,自己用或者是发布到网上供别人使用

【3】第三方模块

别人写的发布到网上,可以免费下载使用

4.模块的四种表现形式(长什么样子)

(1)使用python代码编写的py文件

(2)多个py文件组成的文件夹(包)

(3)已被编译为共享库或DLL的c或c++扩展

(4)使用c编写并链接到python解释器的内置模块

5.模块的两种导入方式

方式一:>>>> import…句型

方式二:>>>> from…import…句型

【1】import导入的底层原理

zyb.py是执行文件 md.py是被导入文件(模块)

ps:相同的模块反复被导入只会执行一次

# md.py
print('from the md.py')
name = 'silence'
money = 2000
def read():
    print('md',money)
    
# zyb.py
import md
name = 'happy'
print(md.name)  #获取的是模块(被导入的文件)名称空间中的name 换成md.money结果就是  2000
print(name)  # 获取当前名称空间中的name
md.read()
# 运行结果
'''
from the md.py
silence
md 2000
'''

【2】import句式特点

可以通过import后面的模块名点的方式,使用模块中所有的数据

并且不会与当前名称空间中的名字冲突

【3】from…import…句型导入的底层原理

ps:相同的模块反复被导入只会执行一次

# md.py
print('from the md.py')
name = 'silence'
money = 2000
def read():
    print('md',money)

# zyb.py
from md import name

print(name)
'''
1.执行当前文件产生一个名称空间
2.执行导入语句 运行模块文件产生名称空间存放运行过程中的所有名字
3.将import后面的名字直接拿到当前执行文件中
'''

【4】from…import…句式特点

1.重复导入也只会导入一次

2.使用模块名称空间中的名字不需要加模块前缀 直接使用即可

3.使用from…import…句式 只能使用import后面出现的名字

​ from…import…简单翻译就是

​ 从….里面拿….来用 没有提到的都不能用

4.缺点就是from…import…的句式会产生名字上的冲突问题

​ 使用时一定要避免名字冲突

# md.py
print('from the md.py')
name = 'silence'
money = 2000
def read():
    print('md',money)

# zyb.py
from md import name
name = 'happy'
print(name)
# 最后输出 happy

【5】导入语法补充说明

(1).可以给模块起别名

语法:mport…as….

​ from…import…as….

# md.py
print('from the md.py')
name = 'silence'
money = 2000
def read():
    print('md',money)

    
# zyb.py    
'''
比如模块很复杂 可以起名简写
'''
import  md as m
print(m.money)

from md import name as n
print(n)
# 输出结果
# from the md.py
# 2000
# silence

(2).连续导入多个模块或者变量名

import time, money,sys…

连续导入多个模块,这多个模块最好有相似的功能部分,如果没有建议分开导入

如果是同一个模块下的多个变量名无所谓

(3).通用导入

from md import *

*表示md里所有的名字 from…import的句式也可以导入所有的名字

如果模块文件使用了双下all限制了可以使用的名字 那么*就会失效 依据双下all后面列举的名字

【二】循环导入问题

【1】问题来源

# a.py
import b

name = 'from a'

print(b.name)
# b.py
import a

name = 'from b'

print(a.name)
# 报错 partially initialized module 'b' has no attribute 'name' 

【2】解决办法

(1)办法一

将导入模块的句式放到定义名字下面

# a.py
name = 'from a'
import b
print(b.name)
# b.py
name = 'from b'
import a
print(a.name)
# 输出结果
# from b
# from a
# from b

(2)办法二

将导入模板的句式写在函数体代码内,只要函数不调用就不会触发导入语句

# a.py
name = 'from a'
def index():
    import b
    print(b.name)
index()
# b.py
name = 'from b'
def index():
    import a
    print(a.name)
index()

【三】判断文件类型

py文件可以被分为两种类型

  • 执行文件
  • 被导入文件
'''
有一个内置变量__name__
    当__name__所在文件是执行文件的时候,结果是__main__
    当__name__所在文件是被导入文件的时候,结果是文件名(模块名)

'''
'''
可以借助__name__区分被导入的代码和测试代码
if __name__ == '__main__':
    当前文件是执行文件的时候才会执行的子代码块
'''
由于上述代码在很多启动脚本中经常使用 所以有简写方式
    直接输入main之后按tab键即可

【四】模块的查找顺序

【1】查找顺序



# 先从自己的局部查
'''
def func():
    import time
'''
# 再从全局查
'''
import time 
'''
# 去内建查
'''
python解释器自带的模块和你安装的模块中查,查出对应的模块再使用
'''
# 去底层 c 语言查
'''
有些功能你点进去看源码发现只要一个 pass
使用c语言写的,但是不想让你看到所有就省略掉了
'''
'''
1.先从内置空间中查找
2.再从内置模块中查找
3.最后去sys.path查找(类似于环境变量)
如果上述三个地方都找不到 那么直接报错
'''

验证sys.path(类似于环境变量)

import sys
print(sys.path) # 结果是一个列表 里面存放了很多路径

sys.path中虽然有很多路径 但是只需要重点关注第一个

第一个其实就是执行文件所在的路径

查找模块的时候只需要站在执行文件所在路径查看即可 有就可以 没有就不行

【2】如何解决sys.path中没有模块所在路径问题

方式一:

主动添加sys.path路径(类似于添加环境变量)

虽然他会爆红,但是还是能找到这个文件

如果从mddd.py中找test.py能否调用找到

也是可以的 理由如下,但是如果关闭 那就找不到了

'''
pycharm会自动将项目目录所在的路径添加到sys.path中
'''

方式二:

利用from…import….句式指名道姓的查找

from aaa import mddd # 从文件夹aaa中导入mddd模块
print(mddd.name)

from aaa.bbb.ccc import mm # 通过点的方式进入下一层目录
print(mm.name)

【5】绝对路径和相对路径

1.相对路径

# D:\Python\PythonProjects\PythonProjects29\zyn
# ./ 表示当前同级目录下
# ../ 表示当前目录的上一级目录
# 默认就是当前目录下
with open('../user_data.text', 'w', encoding='utf-8') as fp:
    fp.write('111')

2.绝对路径

# 在python内部查找的顺序都是绝对路径
import sys
print(sys.path)
# [
# 'D:\\Python\\PythonProjects\\PythonProjects29\\zyn',
# 'D:\\Python\\PythonProjects\\PythonProjects29\\zyn',
# 'D:\\PyCharm\\plugins\\python\\helpers\\pycharm_display',
# 'D:\\Python38\\python38.zip',
# 'D:\\Python38\\DLLs',  # 这里放的就是c语言源码编译后的扩展包
# 'D:\\Python38\\lib', # 放的是内置的模块或者安装的模块
# 'D:\\Python38', # 安装python解释器的路径
# 'D:\\Python38\\lib\\site-packages', # 这里面也有部分安装的的包 ,默认安装到 site-packages
# 'D:\\PyCharm\\plugins\\python\\helpers\\pycharm_matplotlib_backend'# 回到pycharm
# ]

绝对导入和相对导入

在导入模块的时候一切查找模块的句式都是以执行文件为准

​ 无论导入的句式是在执行文件中还是在被导入文件中

绝对导入:

永远按照执行文件的路径一层层往下查找(无脑查找即可)

相对导入:

​ 相对导入打破了必须参照执行文件的所在路径要求,只需要考虑当前模块所在的路径如何使用特殊符号.去查找其他模块即可

from . import a

相对导入只能在被导入文件中使用 不能在执行文件中使用

'''
预备知识
    .表示当前路径
    ..表示上一层路径
    ../..表示上上一层路径
'''

# 模块是功能和集合体,将开发的当前模块的所有功能都放到了一个 模块中
# 加(逻辑验证) 减(逻辑验证) 乘(逻辑验证) 除(逻辑验证)
# 将上述四个模块统一成一个文件夹,从这个文件夹中导入指定的功能即可
# 包就是模块的几何体

# 从专业角度来解释的话
    包就是内部含有__init__.py的文件夹
# 从多角度来解释的话
    包就是多个模块的结合体(内部存放了多个模块文件)
# 在pycharm中甚至直接提供了创建包的选项
    本质就是文件夹里面有一个__init__.py文件
'''
再导入包的时候,索要名字其实是跟包里的__init__.py要
    1.如果想直接通过包的名字使用包里所有的模块,那么就需要在__init__.py中提前导入
    上述方式的好处在于__init__可以提前帮你准备好可以使用的名字
    
    
    2.也可以直接忽略__init__的存在使用绝对导入即可
    上述的好处在于不需要考虑包的存在,直接当成普通文件夹使用即可

'''

json模块

''' json模块是一个序列化模块 ,主要用于跨语言传输'''
1.由下图可知json格式数据是不同编程语言之间数据交互的媒介
2.json格式数据的具体特征
    结论一中:数据基于网络传输肯定是二进制格式
    在python中bytes类型的数据可以直接看成是二进制格式
    在python中只有字符串可以转成bytes类型(编码encode())
# 由上述推论可知 json格式数据 应该属于字符串类型
'''双引号是json格式数据独有的标志'''
json.dumps()     序列化
    将python数据类型转换成json格式字符串
json.loads()     反序列化
    将json格式字符串转换成对应的数据类型

【1】什么是序列化

# 将Python中的字典、列表、元组 ... 转换成 字符串类型
# 如果使用str强制转换数据类型,造成的后果就是转换后的字符串无法转回Python对象

【2】什么是反序列化

# 将字符串类型的数据转换成Python对象(列表、字典、元组 ... )
# 能将python对象转为字符串 --> 字符串转回python对象

【3】json模块

(1)导入json模块

import json

(2)存储数据和读取数据

# (1)序列化保存Python对象数据
user_data_dict = {
    'username': "silence",
    "password": "741"
}

# 存储为json文件数据
'''
with open('user_data.json', 'w', encoding="utf-8") as fp:
    json.dump(obj=user_data_dict, fp=fp)
'''
# 在内部自动将单引号全部转换为双引号,然后保存进去
# 读取
# (2)将json格式数据转换为Python对象
'''
with open('user_data.json', 'r', encoding="utf-8") as fp:
    data = json.load(fp=fp)
print(data, type(data))
'''

(3)转换

# 反序列化和序列化方法之转换
# 我就想将一个字典转换为字符串  转回字典

# (1)将字典转换为字符串格式
data_json_str = json.dumps(obj=user_data_dict)
print(data_json_str, type(data_json_str))  # {"username": "silence", "password": "741"} <class 'str'>


# (2)将字符串转回 python对象
data_json_dict = json.loads(data_json_str)
print(data_json_dict, type(data_json_dict))  # {'username': 'silence', 'password': '741'} <class 'dict'>

(4)保存中文数据

user_data = {'name': "墨漓", "age": 18}
with open('data.json', 'w', encoding='utf-8') as fp:
    json.dump(obj=user_data, fp=fp, ensure_ascii=False)

# 编码和解码
# 编码 encode(编码格式)
# 解码 decode(编码格式)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值