第十三章 模块二和购物车系统搭建
day13模块
1.time模块
# @Author : 大海
# @File : 2.time_test.py
"""
time模块
与时间相关的功能
在python中 时间分为3种
1.时间戳 timestamp 从1970 年 1 月 1日 到现在的秒数 主要用于计算两个时间的差
2.localtime 本地时间 表示的是计算机当前所在的位置
3.UTC 世界协调时间 又称世界统一时间、世界标准时间、国际协调时间。
时间戳 结构化 格式化字符
"""
import time
# 获取时间戳 返回的是浮点型
# 作用 用来计算时间差
print(time.time())
# 获取当地时间 返回的是结构化时间
print(time.localtime())
# 获取UTC时间 返回的还是结构化时间 比中国时间少8小时
print(time.gmtime())
# 结构化时间转换成字符串时间
print(time.strftime('%Y-%m-%d %H:%M:%S'))
# 将格式化字符串的时间转为结构化时间 注意 格式必须匹配
print(time.strptime('2022-05-10 20:51:07','%Y-%m-%d %H:%M:%S'))
# 时间戳 转结构化
# 10秒时间戳
print(time.localtime(10))
# 当前时间戳
print(time.localtime(time.time()))
# 结构化转 时间戳
print(time.mktime(time.localtime()))
# sleep
# 让当前进程睡眠一段时间 单位是秒
time.sleep(1)
print('over')
2.datetime模块
1.补充一下包
1. 什么是包
包就是一个包含有__init__.py文件的文件夹
包本质就是一种模块,即包是用包导入使用的,包内部包含的文件也都是用来被导入使用
2 为何要用包
那文件夹就是用来组织文件的,包就是组织模块的
首次导入包,发生三件事
1. 以包下的__init__.py文件为基准来产生一个名称空间
2. 执行包下的__init__.py文件的代码,将执行过程中产生的名字都丢到名称空间中
3. 在当前执行文件中拿到一个名字p1,该p1就是指向__init__.py名称空间的
包的作用
# 让用户感觉这就是一个模块
# 包可以更新模块,多个模块不会乱
总结包的使用无非注意三点:
1. 导入包就是在导包下的__init__.py文件
2. 使用绝对导入,绝对导入的起始位置都是以包的目录为起始点
3. 但是包内部模块的导入通常应该使用相对导入,用.代表当前所在的文件(而非执行文件),..代表上一级
创建方式
相对路径导入
run.py
import p1
p1.f1()
p1.f2()
2.datetime模块
# @Author : 大海
# @File : datetime.py
"""
datetime
python实现的一个时间处理模块
time 用起来不太方便 所以就有了datetime
总结 datetime相比time 更灵活 更本土化
"""
import datetime
# # 获取时间 获取当前时间 并且返回的是格式化字符时间
print(datetime.datetime.now())
# # 单独获取某个时间 年 月
d = datetime.datetime.now()
print(d.year)
print(d.month)
print(d.day)
print(d.hour)
print(d.minute)
print(d.second)
print(d.microsecond)
# # 手动指定时间
print(datetime.datetime(2018,8,9,9,50,00))
d2 = datetime.datetime(2018,8,9,9,50,00)
print(d-d2)
print(type(d-d2))
# # 替换某个时间单位的值
print(d.replace(year=2019))
# 转换成字符串时间
d_str=d.strftime('%Y-%m-%d %H:%M:%S')
print(d_str)
print(type(d_str))
# timedelta代表两个datetime之间的时间差
print(datetime.timedelta(days=1))
print(datetime.datetime.now()+datetime.timedelta(days=1))
print(type(datetime.timedelta(days=1)))
print(type(datetime.datetime.now()))
# 转换成字符串时间
print((datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S'))
# 增加一天
print((datetime.datetime.now()+datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))
# 减少一天
print((datetime.datetime.now()+datetime.timedelta(days=-1)).strftime('%Y-%m-%d %H:%M:%S'))
print((datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S'))
# 增加一小时
print((datetime.datetime.now()+datetime.timedelta(hours=1)).strftime('%Y-%m-%d %H:%M:%S'))
# 减少一小时
print((datetime.datetime.now()+datetime.timedelta(hours=-1)).strftime('%Y-%m-%d %H:%M:%S'))
print((datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S'))
# 增加一分钟
print((datetime.datetime.now()+datetime.timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S'))
# 减少一分钟
print((datetime.datetime.now()+datetime.timedelta(minutes=-1)).strftime('%Y-%m-%d %H:%M:%S'))
print((datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S'))
# 增加一天,增加一分钟,增加一小时
print((datetime.datetime.now()+datetime.timedelta(days=1,minutes=1,hours=1)).strftime('%Y-%m-%d %H:%M:%S'))
# 减少一天,减少一分钟,减少一小时
print((datetime.datetime.now()+datetime.timedelta(days=-1,minutes=-1,hours=-1)).strftime('%Y-%m-%d %H:%M:%S'))
# 减少一天,增加一分钟,减少一小时
print((datetime.datetime.now()+datetime.timedelta(days=-1,minutes=1,hours=-1)).strftime('%Y-%m-%d %H:%M:%S'))
# 当前时间+加上时间差
print((datetime.datetime.now()+(d-d2)).strftime('%Y-%m-%d %H:%M:%S'))
3.hash模块
什么叫hash: hash是一种算法,该算法接受传入的内容,经过运算得到一串hash值
1.hash值的特点是
1 只要传入的内容一样,得到的hash值必然一样=>文件完整性校验
2 不能由hash值返解成内容===》把密码做成hash值,不应该在网络传输明文密码
3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的,这样不影响传输
2.使用方法
import hashlib
# # 1创建hash工厂
m=hashlib.md5()
# # 2在内存里面运送
# # m.update('helloworld'.encode('utf-8'))
# # 一点一点的给,因为可能二进制会很长 ,这个要好一些
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
# # 3、产出hash值
print(m.hexdigest())
# fc5e038d38a57032085441e7fe7010b0
# fc5e038d38a57032085441e7fe7010b0
3.密码前后加盐
# 输入密码的时候是沿着网络传输到别的服务器上面,黑客可以把包抓下来
# 所以发给服务端是hash值,也就是密文
# 但是还是可以抓下来
# 常用密码字典
# 什么生日 , 123 , 身份证 等等 密码有强烈的个人习惯
# 那么我用一样的hash算法,是不是可以得到一样的hash值 密文 那么明文肯定是一样的
# 撞库风险
# 密码前后加盐
import hashlib
pwd = 'abc123'
m = hashlib.md5()
#
m.update('大海老师'.encode('utf-8'))
m.update(pwd.encode('utf-8'))
m.update('大帅比'.encode('utf-8'))
#
#
print(m.hexdigest())
# 服务器也有相应的规则
# 黑客破解成本远大于收益成本
# 中间加盐
import hashlib
pwd = 'abc123'
m = hashlib.md5()
print(pwd[0])
print(pwd[1:])
m.update('大海老师'.encode('utf-8'))
m.update(pwd[0].encode('utf-8'))
m.update('大帅比'.encode('utf-8'))
m.update(pwd[1:].encode('utf-8'))
m.update('夏洛老师'.encode('utf-8'))
print(m.hexdigest())
4.根据hash算法确定hash的长度
# 3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的,这样不影响传输
import hashlib
pwd = 'hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
m = hashlib.md5()
m.update(pwd.encode('utf-8'))
print(m.hexdigest())
# 7cf8b5ef208ffbdad568a70863292b4a
# 37febe21cac411a046b1b380393dd063
# # sha后面的数字越大加密的算法越复杂
import hashlib
pwd = 'haaaaaaaaaaaaaaaaaaaaaaaaaaaa'
m = hashlib.sha256()
m.update(pwd.encode('utf-8'))
print(m.hexdigest())
# 7a7c76994ace75e34bc34174c26169e0809ea88828137f9b3917fc36e4a40de4
# 6c01f40d88b34e35478279498abfd20b750be6116ae92602fc096a668e3773f3
import hashlib
pwd = 'hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
m = hashlib.sha512()
m.update(pwd.encode('utf-8'))
print(m.hexdigest())
# 394da4cc1c3d3c773dd03e9ef82548ee1dce2126e1e91c1c9f0526bb542c8a2126384ee9b723c6b91b40e701fd453bc3ebe8ae904428b9e7eb57fb0ca90d6b9e
# 29d09ac47225f914370d0037bfd4658f5c6eeb7ba2f6b2ea9233fff8bc6c04f4c7ff602e69920bf5d5f7f04c2d4a3efe46ca51b45f4a96f736965e35fad88958
4.base64模块
1.认识base64
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,
Base64就是一种基于64个可打印字符来表示二进制数据的方法。
定义 8Bit字节代码的编码方式之一
可用于 在HTTP环境下传递较长的标识信息
特性 Base64编码具有不可读性
它只是用传输,并不是加密
Base64编码原理
看一下Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符。
数值代表字符的索引,这个是标准Base64协议规定的,不能更改。
Base64的索引表
2.代码
import base64
a = '大海'
a= a.encode('utf-8')
# print(a)
str_a=base64.b64encode(a)
print(str_a)
# 可以理解成一个中介
# 将base64解码成字符串
str_b = base64.b64decode(str_a).decode('utf-8')
print(str_b)
5.购物车系统搭建
1.项目需求
业务逻辑功能
"1":登录
"2":注册
"3":查看余额
"4":转账
"5":存款
"6":取款
"7":查看流水
"8":购物
"9":查看购买商品
"10":注销
2.一个完整的项目
我们上节课讲了模块
介绍了模块的优势:
1.程序的组织结构更加清晰
2.维护起来更加方便
3.模块可以被重复使用
4.提高了程序员的开发效率
这节课老师就通过这个购物车系统来证明这些优势
需要有的模块目录
运行启动目录文件
bin
start.py
配置文件
conf
setting.py
执行任务文件
core
src.py
数据存储目录
db
db_handle.py
业务逻辑接口
interface
bank.py
shop.py
user.py
公用逻辑接口
lib
common.py
历史日志记录
log
user1.log
那么我们来创建一下项目
1.第一种以shoppingcart为根目录
第一种导入模块不会报红色波浪线
2.第二种不以shoppingcart为根目录创建
第二种导入模块会报红色波浪线,对程序没影响但是会影响效率
第二种报红色波浪线的解决办法
将文件夹Mark Directory as成source root的方法
pycharm标记成项目路径来源文件夹
文件夹变成蓝色
3.代码编写流程
一.启动程序路径配置bin/start.py
1.拿到当前的项目执行目录
import sys
import os
# 拿到当前的执行路径
print(os.path.dirname(__file__))
Source_path = os.path.dirname(os.path.dirname(__file__))
print(Source_path)
2.添加到解释器的路径里面去
sys.path.append(Source_path)
# 添加到解释器路径当中
print(sys.path)
3.启动core/src.py文件run函数
from core import src
if __name__ == '__main__':
src.run()
补充 __ name __
print(__name__)
# # start.py作为执行文件,当前文件作为主程序
运行其他文件比如spam.py
import start
我们看到运行自己print(__ name __ ) 结果是 __ main __ ,而把导入start.py 这个结果确实 start
所有我们就可以通过一个if判断的条件,来判断你的这个文件是不是主程序。
if __ name __ == '__ main __':
if __name__ == '__main__':# 的意思是:只有在本程序直接运行的情况下,才会执行某些操作。
src.run()