学习python-Day22
昨日内容回顾
-
模块的绝对导入与相对导入
-
绝对导入:
- 执行文件所在的sys.path为起始路径,往下一层层查找。
- python会自动将项目的根路径目录添加到sys.path中。所以查找模块在根路径一层层往下找是不会报错的。
- os模块也能找到路径。
-
相对导入:
-
.当前路径 -
..上一层路径 -
`../..``上上一层路径
注意:
相对导入只能在模块文件中使用,不能在执行文件中执行。
相对导入在项目中比较复杂的情况下,可能会出错。
-
-
-
包的概念
- 内部含有
__init__.py文件就是包 - 作用:内部存放多个py文件(模块文件),仅仅是为了更方便的管理模块文件。
- 导入包其实就是导入里面的
__init__.py文件。 - 可以跨过
__init__.py直接将其他模板文件导入包里面。 - python2 必须有
__init__.py文件的文件夹才是包。python3 没那么要求。
- 内部含有
-
编程思想的转变
-
小白阶段
按照需求从上往下推叠代码-单文件
-
函数阶段
将代码按照功能的不同封装成不同的函数-单文件
-
模块阶段
根据功能的不同拆分不同的模块文件-多文件
-
-
软件开发目录规范
- bin---启动文件---start.py
- conf---配置文件---settings.py
- core---核心逻辑---src.py
- lib---公共资源---common.py
- db---数据文件---userinfo.txt
- log---日志文件---log.log
- interface---接口文件---user.py
- readme.txt---编写程序的说明、介绍、广告、类似于产品的说明书
- requirements.txt---所需第三块模块名称和版本
-
常见内置模块
-
collections
collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict。
-
namedtuple:生成可以适应名字来访问元素内容的tuple。坐标系
-
deque:双端队列,高效实现插入和删除操作的双向列表,适合用队列和栈。
-
Counter:计数器,主要用来计数。
-
OrderedDict:有序字典
-
defaultdict:带有默认值的字典
-
-
时间模块之time模块
- 时间戳 time.time() 机器能识别的时间
- 结构化时间 time.gmtime()
- 格式化时间 time.strftime() 人能看懂的时间字符串
-
import time
1.时间戳
print(time.time())
结构化时间
2.本地时间
print(time.localtime())
3.UTC时间,与英国伦敦当地时间一致
print(time.gmtime())
格式化时间(时间字符串)
4.print(time.strftime('%Y-%m-%d %H-%M-%S'))
5.%X可以表示后面的%H-%M-%S
print(time.strftime('%Y-%m-%d %X'))
结构化时间-->时间戳
6.time.mktime(结构化时间)
结构化时间-->字符串时间
7.time.strftime("格式定义","结构化时间")
字符串时间-->结构化时间
8.time.strptime(时间字符串,字符串对应格式)
今日学习内容
注意:py文件名称尽量不要与模块名冲突(内置模块,第三方模块)。
一、时间模块之datetime
import datetime
res = datetime.datetime.today()
res1 = datetime.date.today()
print(res1) #2022-07-15
print(res) # 2022-07-15 16:00:16.239110
print(res.year) # 2022 年
print(res.month) # 7 月
print(res.weekday()) # 4 返回weekday中的星期几,星期一,返回0;星期二,返回1。
print(res.isoweekday()) #星期五
"""
date 年月日
datetime 年月日 时分秒
"""
#timedelta-时间差。有两个datetime数据类型做差得到。
res1 = datetime.date.today()
tl = datetime.timedelta(days=5)
print(res1 + tl) # 2022-07-20
print(res1 - tl) # 2022-07-10
"""
timedelta括号内有很多参数 没有的时间可以通过换算得来
"""
# 补充说明
#读取的时间是系统的本地时间
print(datetime.datetime.now()) #2022-07-15 16:08:42.810107
#读取的时间一直都是系统的“世界标准时间”
print(datetime.datetime.utcnow()) #2022-07-15 08:08:42.810107
#以时间字符串的形式
c =datetime.datetime(2017, 5, 23, 12, 20)
print('指定日期:', c) #指定日期: 2017-05-23 12:20:00
二、os模块
os模块主要跟当前程序所在的操作系统打交道。
import os
'''
1.创建目录
当前这个运行文件同层次来创建文件夹
'''
os.mkdir(r'aaa') # 创建单级目录
os.mkdir(r'bbb\ccc\ddd') # mkdir无法创建多级目录
os.makedirs(r'bbb\ccc\ddd') # makedirs可以创建多级目录
os.makedirs(r'ccc') # makedirs也可以创建单级目录
'''
2.删除目录
当前这个运行文件同层次来删除文件夹
'''
os.rmdir(r'aaa') #删除但单级目录。
os.rmdir(r'ccc') #如果单级目录下有其他数据就不能删除。也不支持多级删除!
os.removedirs(r'ccc') #针对有数据的目录是没法删除的。
os.removedirs(r'bbb\ccc\ddd') #由内到外递归删除空目录,直到有数据的目录为止。
'''
3.列举指定路径下的文件名称(文件、目录)
当前执行文件所在同一层的文件
'''
print(os.listdir()) # 结果是列表 ['one.py', 'three.py', 'two.py']
print(os.listdir(r'D:\\Typora')) #指定D盘的Typora中文件结果以列表的形式
['chrome_100_percent.pak',
'chrome_200_percent.pak',
'd3dcompiler_47.dll',
'DO NOT ADD FILES HERE.md',
'ffmpeg.dll',
'icudtl.dat',
'libEGL.dll',
'libGLESv2.dll',
'LICENSE',
'LICENSES.chromium.html',
'locales',
'MyNote',
'resources',
'resources.pak',
'snapshot_blob.bin',
'swiftshader',
'Typora.exe',
'unins000.dat',
'unins000.exe',
'v8_context_snapshot.bin',
'version',
'vk_swiftshader.dll',
'vk_swiftshader_icd.json',
'vulkan-1.dll',
'笔记']
4.重命名文件 删除文件
os.rename(r'two.py', r't.py') #前面是要修改的文件名,后面是修改后的文件名
os.remove(r't.py') # 删除指定文件
5.获取当前执行文件路径(所在的路径) 绝对路径
print(os.getcwd()) #D:\pythonProject\day23\xc
#返回上一层创建一个文件夹 ,获得该文件的绝对路径
os.chdir(r'..') # 返回上一层
os.mkdir(r'xzxz') # 建一个文件夹
print(os.getcwd()) #D:\pythonProject\day23
6.与程序启动文件相关
# 获取当前文件的绝对路径(可以不记)
print(os.path.abspath(__file__)) # D:\pythonProject\day23\xc\one.py
# 获取当前文件所在的目录路径(必须得记)
print(os.path.dirname(__file__)) #D:/pythonProject/day23/xc
7.判断路径是否存在(文件、目录)
print(os.path.exists(r'three.py')) #True
print(os.path.exists(r'xzxz')) #False
print(os.path.exists(r'two.py')) #False
print(os.path.exists(r'two')) #True
8.判断是否是文件夹或者目录
print(os.path.isdir(r'three.py')) #False
print(os.path.isdir(r'two')) #True
print(os.path.isdir(r'xzxz')) #False 不在执行文件所在的路径判断不出
print(os.path.isfile(r'three.py')) #True
print(os.path.isfile(r'two')) #False
8.拼接路径
relative_path = 'aaa.txt'
'''拼接a.txt的绝对路径'''
absolute_path = r'D:\pythonProject\day23\xc'
print(absolute_path + relative_path) #D:\pythonProject\day23\xc\\aaa.txt
'''
文件间的斜杠和反斜杠在不同的操作系统是不一样的。
join方法可以自动识别当前所在的操作系统并自动切换正确的分隔符 windows用\ mac用/
涉及到路径拼接 不要使用加号 建议使用os模块的里面join方法"
'''
res = os.path.join(absolute_path, relative_path)
print(res) #D:\pythonProject\day23\xc\aaa.txt
9.获取文件大小 bytes为单位。一个英文字母是1字节,一个汉字为3个字节。
print(os.path.getsize(r'three.py')) # 11
print(os.path.getsize(r'aaa.txt')) # 6
三、sys模块
sys模块主要是跟python解释器打交道。
import sys
#结果是列表
print(sys.path)
#查看解释器信息
print(sys.version)
#3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)]
#查看当前平台
print(sys.platform) #win32
#sys.argv 命令行参数,实现从程序外部向程序传递参数。
res = sys.argv
'''需求:命令行执行当前文件必须提供用户名和密码,否则不准执行'''
#判断用户有没有传值
if len(res) == 3:
username = res[1]
password = res[2]
if username == 'xz' and password == '123':
print('可执行功能')
else:
print('用户名或密码错误')
else:
print('请输入用户名或密码,二者不可兼得')
1.Terminal 相当于 cmd 终端。
2.找到执行文件说在的路径,D:\pythonProject\day23\xc>,可以执行 one.py ,也可以在里面加参数。
3.用空格隔开后结果就是用列表的形式。
上述校验用异常捕获来做
try:
username = res[1]
password = res[2]
if username == 'xz' and password == '123':
print('可执行功能')
else:
print('用户名或密码错误')
except Exception as e:
print('未输入用户名或密码,两者不能或缺')
四、json模块
-
json模块也称为
序列化模块 -
json模块是不同编程语言之间数据交互必备的模块(处理措施)
-
json格式的数据应该是什么?
数据基于网络传输肯定是二进制,那么在python中只有字符串可以调用encode方法转换成二进制数据,所以json格式的数据也属于字符串。
-
json格式的数据有一个很明显的特征
- 字符串类型
- 引号是标志性的双引号
d = {'name': 'xz', 'pwd': 123}
# 需求:将上述字典保存到文件中 并且将来读取出来之后还是字典
方式1:
with open(r'b.txt', 'w', encoding='utf8') as f:
#将其转化成字符串类型
f.write(str(d))
with open(r'b.txt', 'r', encoding='utf8') as f:
data = f.read()
print(data, type(data))#结果还是字符串类型
上述方式行不通,因为输出的结果还是以字符串的形式。所以怎么才能做到,以字典转化成字符串写进文件,再以字符串转化成字典形式读出。用json!!!
import json
# 序列化
res = json.dumps(d) #将其他数据类型转换成json格式字符串
print(res, type(res)) #{"name": "xz", "pwd": 123}
# d1 = {"name": "jason", "pwd": 123}
# print(d1) # {'name': 'jason', 'pwd': 123}
# 反序列化
res1 = json.loads(res) #将json格式字符串转换成对应编程语言中的数据类型
print(res1, type(res1)) # {'name': 'xz', 'pwd': 123}
方式2:json模块
import json
d = {'name': 'xz', 'pwd': 123}
with open(r'b.txt', 'w', encoding='utf8') as f:
#f.write(json.dumps(d))
json.dump(d, f) # 直接让字典写入文件(json自动帮你完成转换)
with open(r'b.txt', 'r', encoding='utf8') as f:
# data = f.read()
# res = json.loads(data)
res = json.load(f)
print(res, type(res)) #{'name': 'xz', 'pwd': 123}
json有四个方法,两两搭配。
| dumps() | loads | dump | load | |
|---|---|---|---|---|
| 作用 | 将其他数据类型转换成json格式字符串 | 将json格式字符串转换成对应的数据类型 | 将其他数据数据以json格式字符串写入文件 | 将文件中json格式字符串读取出来并转换成对应的数据类型 |
| 举例 | f.write(json.dumps(d)) | data = f.read() res = json.loads(data) | json.dump(d, f) | res = json.load(f) |
五、json模块的实参
涉及到用户数据的存储 可以单用户单文件
import json
import os
#执行文件所在的路径下的目录,结果为列表的形式
base_dir = os.path.dirname(__file__)
#拼接,找出db的绝对路径
db_path = os.path.join(base_dir, 'db')
#如果找不到db文件夹
if not os.path.exists(db_path):
#新建一个db文件夹
os.mkdir(db_path)
#注册
#获取用户信息以字典的形式保存
username = input('username>>>:').strip()
password = input('password>>>:').strip()
#建个字典
user_dict = {
'name': username,
'pwd': password,
'balance': 999999,
'shop_car': []
}
#找出要写入文件的路径
file_path = os.path.join(db_path, '%s' % username)
with open(file_path, 'w', encoding='utf8') as f:
#利用dump转换成字符串并写入文件的方式
json.dump(user_dict, f)
#登录
#可以直接写用户名所在的路径
base_dir = r'D:\pythonProject\day23\xc\db'
username = input('username>>>:').strip()
#列出db文件夹用户文件的列表
username_list = os.listdir(base_dir)
if username in username_list:
# 拼接,找出每个用户名文件的绝对路径
file_path = os.path.join(base_dir, username)
with open(file_path, 'r', encoding='utf8') as f:
#找到文件就写入
data = json.load(f)
print(data, type(data))
作业
'''1.编写一个统计指定文件类型的脚本工具
输入指定类型的文件后缀
eg:.txt
并给出一个具体路径 之后统计该类型文件在该文件下的个数
ps:简单实现即可 无需优化'''
import os
import sys
#找到执行列表的路径
file_path = os.path.dirname(__file__)
#找到该路径下的文件夹列表
file_list = os.listdir(file_path)
#print(file_list)
file_d = input('输入指定类型的文件后缀>>>')
count = 0
#for循环出每个列表的数据值-文件名
for f in file_list:
#将文件和路径拼接,
file_n = os.path.join(file_path, f)
#判断该路径的后面结尾以输入文件后缀的话,就自+1
if file_n.endswith(file_d):
count += 1
print(count)
'''2.针对json实操 尝试单文件多用户(一行一个)是否可实现 哪个更方便'''
#执行文件所在的路径下的目录,结果为列表的形式
base_dir = os.path.dirname(__file__)
#拼接,找出db的绝对路径
db_path = os.path.join(base_dir, 'db')
#如果找不到db文件夹
if not os.path.exists(db_path):
#新建一个db文件夹
os.mkdir(db_path)
if choice == '1':
# 注册
# 获取用户信息以字典的形式保存
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 建个字典
user_dict = {
'name': username,
'pwd': password,
'balance': 999999,
'shop_car': []
}
# 找出要写入文件的路径
file_path = os.path.join(db_path, 'user_data')
with open(file_path, 'a', encoding='utf8') as f:
# 利用dump转换成字符串并写入文件的方式
data = json.dumps(user_dict) + '\n'
f.write(data)
#json.dump(user_dict, f)
'''
我觉得各有各的好处和坏处:
如果是大量数据不做排版要求的话,可以用一行多个用户。采用dump。
如果想用一行一个用户就用dumps
'''
'''3.编程小练习
有一个目录文件下面有一堆文本文件
eg:
db目录
J老师视频合集
R老师视频合集
C老师视频合集
B老师视频合集
文件内容自定义即可 要求循环打印出db目录下所有的文件名称让用户选择
用户选择哪个文件就自动打开该文件并展示内容
涉及到文件路径全部使用代码自动生成 不准直接拷贝当前计算机固定路径'''
os.chdir(r'..')
#print(os.getcwd())
db_path = os.path.join(os.getcwd(), 'db')
#print(db_path)
file_list = os.listdir(db_path)
while True:
for i in file_list:
print('文件有:', i)
file_chioce = input('你选择的内容>>>:').strip()
if file_chioce in file_list:
file_path = os.path.join(db_path, file_chioce)
with open(file_path, 'r', encoding='utf8') as f:
res = json.load(f)
print('%s:' % file_chioce, res)