[7天速成Python——第七天]
今天是python教学的最后一天,在这里非常非常非常非常非常非常非常感谢武沛奇老师,他的教学非常有趣生动,如果大家有兴趣,可以去B站上搜索银角大王武沛奇老师的python课!谢谢大家
什么是模块和包呢?
模块,就是指py文件,我们可以将一些功能按照某个中维度划分。
自定义
内置
第三方
包,就是指文件夹,我们可以将一些功能按照某个中维度划分。
里面包含多个py文件。
一般情况下,大家平时的讨论和沟通时,一般都统称为:模块。
接下来我们要学习模块和包时:
gx_day07
├── app.py
└── utils.py
# app.py
# 1.导入utils模块
import utils
choice = input("请输入序号:")
# 2.调用utils模块中的str_to_int功能。
res = utils.str_to_int(choice)
if res == None:
print("输入错误")
else:
msg = "序号是:{}".format(res)
print(msg)
# utils.py
def str_to_int(str_data):
"""
字符串转换为整形
:param str_data: 要转换的字符串
:return: 整形 or None(无法转换)
"""
if str_data.isdecimal():
return int(str_data)
return None
def f1():
pass
def f2():
pass
示例2:
gx_day07
├── app.py
├── commons
│ ├── pager.py
│ └── pool.py
└── utils.py
# app.py
# 导入
import utils
import commons.pager
import commons.pool
# 调用
v1 = commons.pager.pppppppp()
print(v1)
v2 = commons.pool.ooooooooo()
print(v2)
v3 = utils.str_to_int("123123")
print(v3)
上述的案例中,我是把包和模块都放在了:
如果我想要把某个模块放在 F:\code\hello.py
,导入到我的项目里来,默认一定是无法导入的,这是因为Python内部在看待 import xxx
自动回去某一些目录中寻找。
import hello
import sys
print(sys.path)
[
'/Users/wupeiqi/PycharmProjects/gx_day07',
'/Users/wupeiqi/PycharmProjects/gx_day07',
'/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_display',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/requests-2.26.0-py3.9.egg',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/charset_normalizer-2.0.7-py3.9.egg',
'/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_matplotlib_backend']
以上只是了解后,如果你需要让python导入模块是去自定定义的目录中寻找,那么你就需要:
import sys
# 1.自定义文件所在的目录添加到sys.path
sys.path.append(r"F:\code")
# 2.导入
import hello
问题:sys.path获取到的是个什么?
import xx
是个列表,列表是有序。
[
'/Users/wupeiqi/PycharmProjects/gx_day07',
'/Users/wupeiqi/PycharmProjects/gx_day07',
'/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_display',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
]
注意:千万不要让自己的模块名称和python内置模块的名称同名(此时你想去调用Python内置的模块中的功能时,无法调用)。
import utils
utils.u_f1()
import commons.pager
commons.pager.p_1()
from utils import u_f1
u_f1()
from commons.pager import p_1
p_1()
from commons import pager
pager.p_1()
from commons.pager import p_1, p_2, p_3
from commons.pager import *
p_1()
p_2()
p_3()
p_4()
from commons.pager import p_1 as p2
def p_1():
return "ppppp"
p_1()
p2()
答疑:
import 和 from 两种方式都是导入模块,效果上相同。一般情况下:
- 多个层级
from commons.xxx.xxx import sdf
- 单层目录(与运行的py文件在同级目录)
import xx
sys.path
import sys
sys.path.append(".....")
import xx
自己的模块不要内置的重名。
导入的方式:import / from xx import xxx
Python内部提供好的功能。
是一个对数据进行加密的模块。
import hashlib
data = "admin"
obj = hashlib.md5()
obj.update(data.encode('utf-8'))
res = obj.hexdigest()
print(res)
在以后咱们开发项目时,密码不要用明文存储。
wupeiqi,21232f297a57a5a743894a0e4a801fc3
为了防止数据库泄露,用户名和密码全都泄露。
MD5加密,不可反解。
admin -> 21232f297a57a5a743894a0e4a801fc3
案例:以后登录时候要进行密文匹配。
user_dict = {
"wupeiqi":"21232f297a57a5a743894a0e4a801fc3"
}
user = input("用户名:") # wupeiqi
pwd = input("密码:") # admin
db_pwd = user_dict.get(user) # 21232f297a57a5a743894a0e4a801fc3
# 将 pwd 进行加密的到密文:21232f297a57a5a743894a0e4a801fc3
有些人搞一些机器跑,把明文的密文跑。
admin adfasdfasdfasdf 123 asdfadfasdfasdfasdf ffsdf asdfadfasdfasdfasdf
import hashlib
data = "admin"
salt = "asidfjaksdkjasdiuofiqjskda91qw3asdf"
obj = hashlib.md5(salt.encode('utf-8'))
obj.update(data.encode('utf-8'))
res = obj.hexdigest()
print(res) # c06b63d965921fe0a8803071b623e4e9
用户注册案例:
import hashlib
DB_FILE_PATH = "db.txt"
SALT = "asidfjaksdkjasdiuofiqjskda91qw3asdf"
def md5(data_string):
obj = hashlib.md5(SALT.encode('utf-8'))
obj.update(data_string.encode('utf-8'))
res = obj.hexdigest()
return res
def login():
""" 登录 """
print("用户登录")
user = input("用户名:")
pwd = input("密码:")
encrypt_pwd = md5(pwd)
# 逐行读取文件中的内容,来进行比较
is_success = False
with open(DB_FILE_PATH, mode='r', encoding='utf-8') as file_object:
for line in file_object:
data_list = line.strip().split(',')
if data_list[0] == user and data_list[1] == encrypt_pwd:
is_success = True
break
if is_success:
print("登录成功")
else:
print("登录失败")
def register():
""" 注册 """
print("用户注册")
user = input("用户名:")
pwd = input("密码:")
encrypt_pwd = md5(pwd)
line = "{},{}\n".format(user, encrypt_pwd)
with open(DB_FILE_PATH, mode='a', encoding='utf-8') as file_object:
file_object.write(line)
def run():
func_dict = {
"1": register,
'2': login
}
print("1.注册;2.登录")
choice = input("序号:")
func = func_dict.get(choice)
if not func:
print("序号选择错误")
return
func()
run()
帮助我们生成一些随机数据。
import random
v1 = random.randint(1, 20) # 大于等于1; 小于等于20
print(v1)
案例:
import random
data_list = ["陈青", "邓新成", "谢鹏", "梁世斌"]
# 获取随机索引值 1
idx = random.randint(0, len(data_list) - 1)
# 调用列表的pop功能,将列表中的某个索引位置的元素删除
# 将删除那个值获取到
element = data_list.pop(idx)
print(element)
print(data_list)
import random
char_list = []
for i in range(6):
num = random.randint(65, 90)
char = chr(num)
char_list.append(char)
res = "".join(char_list)
print(res)
random模块中的其他常用功能:
import random
# 1.获取随机的整数
v1 = random.randint(1, 20) # 大于等于1; 小于等于20
print(v1)
# 2.获取随机的小数
v2 = random.uniform(1, 10)
print(v2)
# 3.随机抽取1个数
data_list = [11, 22, 33, 44, 55]
v3 = random.choice(data_list)
print(v3)
# 4.随机抽取多个数
data_list = [11, 22, 33, 44, 55]
v4 = random.sample(data_list, 3)
print(v4)
# 5.打乱顺序
num_list = [i for i in range(100)]
random.shuffle(num_list)
print(num_list)
案例:年会抽奖案例
import random
# 1.创建300名员工
"""
user_list = []
for i in range(1, 301):
item = "工号-{}".format(i)
user_list.append(item)
"""
user_list = ["工号-{}".format(i) for i in range(1, 301)]
# for i in range(100):
# user_list.append("工号-137")
#
# print(user_list)
# 2.奖项信息
data_list = [
("三等奖", 5),
("二等奖", 3),
("一等奖", 2),
("特等奖", 1)
]
# 3.抽奖
for item in data_list:
input("点击回车,继续抽奖:")
text = item[0]
count = item[1]
if text == "特等奖":
message = "荣获特等奖的名单:郭智。"
print(message)
break
# 抽取count=5个员工,恭喜他们获得 ["工号1",...]
lucky_user_list = random.sample(user_list, count)
for name in lucky_user_list:
user_list.remove(name)
user_string = "、".join(lucky_user_list)
message = "荣获{}的名单:{}。".format(text, user_string)
print(message)
本质上:是一种数据格式,字符串形式。
用处:让不同编程语言之间实现数据传输。
JSON格式:
外部整体大的字符串
json字符串的内部如果有字符串的话,一定需要用双引号。
json字符串中不会存在python中的元组那样的格式。
info = {'k1':123,'k2':(11,22,33,44)}
JSON格式:
'{"k1":123,"k2":[11,22,33,44] }'
以下哪些数据是JSON格式的字符串:
v1 = '{"k1":123,"k2":456}'
v2 = "{'k1':123,'k2':456}"
v3 = '{"k1":123,"k2":456,"k3":[11,22,33]}'
v4 = '{"k1":123,"k2":456,"k3":(11,22,33)}'
import json
info = {'k1': 123, 'k2': (11, 22, 33, 44)}
# python的数据类型转换为JSON格式的字符串
res = json.dumps(info)
print(res) # '{"k1": 123, "k2": [11, 22, 33, 44]}'
import json
data_string = '{"k1": 123, "k2": [11, 22, 33, 44]}'
# 将JSON格式的字符串转换为Python的数据类型
res = json.loads(data_string)
print(res)
print(res['k1'])
print(res['k2'])
print(res['k2'][-1])
问题:JSON字符串和普通的字符串有什么区别?
v1 = "asdfasdkfasdfasd"
v2 = "[11,22,33]"
问题:
v1 = "(3,6)" # 是JSON格式的字符串吗?
import json
info = {"name": "邱恩婷", "age": 19}
v1 = json.dumps(info, ensure_ascii=False)
print(v1) # {"name": "邱恩婷", "age": 19}
在Python中默认只能通过json模块序列化基本的数据类型。
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+
# 可以序列化(执行正确)
import json
import decimal
info = {"name": "邱恩婷", "age": 19.5, 'f': True, "hobby": None}
v1 = json.dumps(info, ensure_ascii=False)
print(v1)
import json
import decimal
data = decimal.Decimal("0.3")
res = float(data)
info = {"name": "邱恩婷", "age": 19.5, 'f': True, "hobby": None, "data": res}
v1 = json.dumps(info, ensure_ascii=False)
print(v1)
案例1:基于requests模块向豆瓣发送请求获取他热门电影。
import json
import requests
res = requests.get(
url="https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20",
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
}
)
data_dict = json.loads(res.text)
for item in data_dict['subjects']:
print(item['title'], item['url'])
案例2:用Python写一个网站,给Java程序提供数据支持。
pip install flask
import json
from flask import Flask
app = Flask(__name__)
@app.route('/get/info')
def index():
data = ['武沛齐', '郭智', '住户费']
json_string = json.dumps(data, ensure_ascii=False) # JSON格式的字符串
return json_string
@app.route('/do/play')
def play():
info = {
"code": 1000,
'status': True,
'values': [
{"id": 1, "name": "武沛齐"},
{"id": 2, "name": "陈青"},
{"id": 3, "name": "梁树彬"},
]
}
json_string = json.dumps(info, ensure_ascii=False) # JSON格式的字符串
return json_string
if __name__ == '__main__':
app.run()
import time
# 1.获取当前的时间戳 (自1970年1月1日开始)
v1 = time.time()
print(v1) # 1636956070.0133471 / 1636956095.6416771
案例:
import time
start_time = time.time()
...
....
end_time = time.time()
interval = end_time - start_time
print(interval)
import time
# 1.获取当前的时间戳 (自1970年1月1日开始)
# v1 = time.time()
# print(v1) # 1636956070.0133471 / 1636956095.6416771
# 2.停止N秒,再继续运行
while True:
print(1)
time.sleep(1)
时间戳。
import time
v1 = time.time()
datetime格式
import datetime
v1 = datetime.datetime.now()
print(v1) # datetime类型
字符串格式
import datetime
ctime_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(ctime_string)
用户注册
while循环,输入:用户名、密码
密码-> md5加密 -> 密文
当前时间,用户注册时间。
写入到db.txt文档中
user,pwd,时间
"""
1. 代码复用
2. 代码太长,拆分到不同的函数
"""
import hashlib
import datetime
def md5(data_string):
obj = hashlib.md5()
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()
def run():
while True:
user = input("用户名:")
password = input("用户名:")
encrypt_password = md5(password)
ctime_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
line = "{},{},{}\n".format(user, encrypt_password, ctime_string)
with open('db.txt', mode='a', encoding='utf-8') as f:
f.write(line)
# f = open('db.txt', mode='a', encoding='utf-8')
# f.write(line)
# f.close()
run()
日志记录器,按分钟的维度来创建文件,并将内容写入到文件中。
写一个函数,在函数中实现这个功能。
在函数里面
循环让用户输入:文本
需要将文本写入到文件中。
import datetime
# 2021-11-15-14-53.txt
ctime_string = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")
print(ctime_string)
import datetime
def run():
while True:
text = input(">>>")
ctime_string = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")
file_name = "{}.txt".format(ctime_string)
f = open(file_name, mode='a', encoding='utf-8')
f.write("{}\n".format(text))
f.close()
run()
字符串 -> datetime类型
from datetime import datetime
text = "2021-11-11"
res = datetime.strptime(text, "%Y-%m-%d")
print(res,type(res))
datetime -> 字符串
from datetime import datetime
dt = datetime.now()
res = dt.strftime("%Y-%m-%d-%H-%M")
print(res)
时间戳 -> datetime类型
import time
from datetime import datetime
ctime = time.time()
dt = datetime.fromtimestamp(ctime)
print(dt, type(dt))
datetime类型 -> 时间戳
from datetime import datetime
v1 = datetime.now()
res = v1.timestamp()
print(res)
from datetime import datetime, timedelta
v1 = datetime.now()
# res = v1 + timedelta(days=280)
# print(res, type(res))
res = v1 + timedelta(days=10, hours=20, minutes=10, seconds=100)
# print(res, type(res))
date_string = datetime.strftime(res, "%Y-%m-%d-%H-%M")
print(date_string)
很方便的可以帮我们处理时间加减。
路径的拼接
window系统: C:\xx\xxx\xxx
Mac系统: /user/xxx/xxx/xxx
Linux系统: /user/xxx/xxx/xxx
import os
path = os.path.join("x1","x2","x3","x4",'log.txt')
print(path) # x1/x2/x3/x4/log.txt
找到上级目录
import os
file_path = "x1/x2/x3/x4"
# 找到当前路径的上一级目录
v1 = os.path.dirname(file_path)
print(v1) # x1/x2/x3
绝对路径
绝对路径:
/Users/wupeiqi/PycharmProjects/gx_day07/2021-11-15-15-10.txt
相对路径(当前执行的程序)
见下图
如何生成一个绝对路径。
import os
res = os.path.abspath("xx")
# 当前程序所在目录 相对目录
# /Users/wupeiqi/PycharmProjects/gx_day07/ xx
print(res)
判断路径是否存在
import os
res = os.path.exists(file_path)
print(res) # True/False
import os
# files/db.txt
file_path = os.path.join('files', 'db.txt')
# 判断路径是否存在
if os.path.exists(file_path):
# 读取文件时,如果文件不存在就会报错:FileNotFoundError
f = open(file_path, mode='r', encoding='utf-8')
data = f.read()
f.close()
print(data)
else:
print("文件不存在")
创建文件夹
import os
path = os.path.join('db', '2021', '11月份')
print(path) # db/2021/11月份
os.makedirs(path)
import os
# path = "db/2021/11月份"
path = os.path.join('db', '2021', '11月份')
if not os.path.exists(path):
# 创建目录
os.makedirs(path)
删除文件、文件夹
import os
path = os.path.join('db', '2021', '11月份', 'log.txt')
# 删除文件
os.remove(path)
import os
import shutil
path = os.path.join('db', '2021')
# 删除文件夹
shutil.rmtree(path)
判断是否是文件夹
import os
path = os.path.join('db', 'a1.txt')
res = os.path.isdir(path)
print(res)
os.listdir/os.walk
import os
# 查看某个目录下的所有的文件和文件夹(一级目录)
for item in os.listdir("/Users/wupeiqi/Documents/视频教程/路飞Python/mp4/开篇"):
print(item)
"""
03 开篇:学习方法的建议.mp4
.DS_Store
02 开篇:授课模式须知.mp4
课堂笔记
05 开篇:写在最后.mp4
04 开篇:笔记和文档的编写.mp4
01 开篇:讲师和课程内容介绍.mp4
"""
import os
# 查看某个目录下的所有的文件和文件夹
for in_path, folder_list, name_list in os.walk("/Users/wupeiqi/Documents/视频教程/路飞Python/mp4/开篇"):
for name in name_list:
abs_path = os.path.join(in_path, name)
print(abs_path)
案例:找到某个目录下的所有 含有某个关键字 的文件(文件路径)
import os
target_folder_path = "/Users/wupeiqi/Documents/视频教程/路飞Python/mp4"
key = "练习"
# 查看某个目录下的所有的文件和文件夹
for in_path, folder_list, name_list in os.walk(target_folder_path):
for name in name_list:
if key in name:
abs_path = os.path.join(in_path, name)
print(abs_path)
案例:
"""
用户注册:
- 用户信息需要存储在 db/users/account.txt
"""
import os
while True:
user = input(">>>")
line = "{}\n".format(user)
# 确保文件所在目录已存在 db/users(不存在,就创建)
folder_path = os.path.join("db", "files")
if not os.path.exists(folder_path):
os.makedirs(folder_path)
# 所在文件夹必须已存在
file_path = os.path.join(folder_path, 'account.txt')
file_object = open(file_path, mode='a', encoding='utf-8')
file_object.write(line)
file_object.close()
新创建一个项目
创建一个app.py的文件,这个文件实现所有的代码。
业务需求
import os
import datetime
# DB_FOLDER = os.path.join("db", 'files')
DB_FOLDER = "db"
def history(user_file_path):
""" 历史记录 """
# 1.监测文件是否存在?不存在,输出:无历史记录
if not os.path.exists(user_file_path):
print("无历史记录")
return
# 2.读取文件的内容逐行打印(历史订票信息)
print("=====历史记录=====")
with open(user_file_path, mode='r', encoding='utf-8') as f:
for line in f:
line = line.strip()
print(line)
def booking(user_file_path):
""" 预定 """
location = input("请输入景区名称:")
count = input("订票数量:")
ctime_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
line = "{},{},{}\n".format(location, count, ctime_string)
with open(user_file_path, mode='a', encoding='utf-8') as file_object:
file_object.write(line)
def run():
# 1.检查文件夹是否存在
if not os.path.exists(DB_FOLDER):
os.makedirs(DB_FOLDER)
# 2.输入用户名,监测是老用户还是新用户
name = input("请输入姓名:")
# db/用户名.txt
file_path = os.path.join(DB_FOLDER, "{}.txt".format(name))
if os.path.exists(file_path):
print("欢迎再次回来,老用户")
else:
print("欢迎首次使用,新用户")
# 3.功能的选择
func_dict = {"1": history, "2": booking}
while True:
print("1.查询历史订单;2.预定")
choice = input("请选择(q/Q):")
if choice.upper() == 'Q':
return
func = func_dict.get(choice)
if not func:
print("序号输入错误,重新输入")
continue
func(file_path)
run()