python学习第四周总结
异常常见类型
异常处理语法结构
异常补充处理
异常处理实战应用
生成器对象
自定义生成器range()功能
yield冷门用法
生成器表达式
模块简介
模块的分类
导入模块的两种句式
导入模块补充说明
循环导入问题
判断文件类型
模块的查找顺序
绝对导入和相对导入
包
包的导入使用
collections模块
time模块
random模块
os模块
sys模块
json模块
软件开发目录规范
软件开发目录
异常常见类型
SyntaxError:语法错误
NameError:名字错误,一般由于变量名未定义造成
IndexError:索引错误,列表索引值超过了范围
KeyError:字典键错误,字典的键找不到
IndentationalError:缩进错误
异常处理语法结构
1.基本语法结构:
try:
待检测代码
except 错误类型
错误类型正确执行的代码
try:
l1 = [1,2,3,4]
l1[4]
except IndexError:
print('索引出现错误') # 索引出现错误
"""
如果except后面的错误类型正确,那么就不会报错,而是直接执行except的子代码,错误类型不对还是会报错
"""
2.查看错误信息:加一个e可以查看具体错误
try:
待监测的代码(可能会出错的代码)
except 错误类型 as e:
针对上述错误类型指定的方案
try:
print(name)
except NameError as e:
print(e) # name 'name' is not defined
3.如果不确定是哪种错误类型,可以采用上面的格式。但是该形式找到地一个错误类型之后就会停止运行,也就是说运行一次只能找到一处错误
针队不同的错误类型制定不同的解决方案,但是还是要写明错误类型
try:
待监测的代码(可能会出错的代码)
except 错误类型1 as e:
针对上述错误类型指定的方案
except 错误类型2 as e:
针对上述错误类型指定的方案
except 错误类型3 as e:
针对上述错误类型指定的方案
try:
print(name)
l1 = [1,2,3,4]
l1[4]
except IndexError as e:
print(e)
except NameError as e:
print(e)
4.万能异常:无序写错误类型,一次只能检测出一次错误,修改完毕之后才能检测下一次错误
try:
待监测代码(可能会出现的代码)
except Exception as e:
针队各种常见的错误类型全部统一处理
try:
print(name)
l1 = [1,2,3,4]
l1[4]
except Exception as e:
print(e)
5.结合else使用:被监测代码没有错误时执行else子代码
try:
待监测的代码(可能会出现错误的代码)
except Exception as e:
针队各种常见的错误类型全部统一处理
else:
try的子代码正常运行结束没有任何的报错后 再执行else子代
try:
print(name)
l1 = [1,2,3,4]
l1[4]
except Exception as e:
print(e)
else:
print('错误已检测完毕')
6.结合finally使用:
try:
待监测的代码(可能会出现错误的代码)
except Exception as e:
针队各种常见的错误类型全部统一处理
else:
try的子代码正常运行结束没有任何的报错后 再执行else子代
finally:
无论try子代码是否报错,最后都要执行finally子代码
try:
print(name)
l1 = [1,2,3,4]
l1[4]
except Exception as e:
print(e)
else:
print('错误已检测完毕')
finally:
print('111')
异常处理补充
1.断言:关键字assert,后面的代码如果是对的name会执行下面的代码,是错的直接会报错
name = 'jason'
assert isinstance(name, str)
print('断言对了会执行吗') # 断言对了会执行吗
name = 'jason'
assert isinstance(name, int)
print('断言错了会执行吗') # 报错
2.主动抛异常:如果不满足条件则会执行else分支结构,满足条件则直接报错
name = 'jason'
if name == 'max':
raise Exception('111')
else:
print('222') # 222
异常处理实战应用
1.异常处理能尽量少用就少用
2.被try监测的代码能尽量少就尽量少
3.当代码中可能会出现一些无法控制的情况报错才应该考虑使用
eg: 使用手机访问网络软件 断网
编写网络爬虫程序请求数据 断网
练习:使用while循环+异常处理+迭代器对象 完成for循环迭代取值的功能
l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
new_l1 = l1.__iter__()
while True:
try:
print(new_l1.__next__())
except Exception as e:
break
生成器对象
1.本质:内置有__iter__和__next__的迭代器对象
2.区别:
2.1 迭代器对象是解释器自动提供的,由数据类型,文件对象转变为迭代器对象
2.2 生成器对象是由程序员编写出来的
3.创建生成器的基本语法:函数体代码中填写yield关键字
"""
1.函数体代码中有yield关键字,name函数名加括号不会执行函数体代码,而是会生成一个生成器对象
"""
def my_iter():
print('生成器就是迭代器的一种')
yield
my_iter() # 生成一个生成器对象
"""
2.把加括号的结果赋值给一个变量名,变量名调用__next__才会执行函数体代码
"""
def my_iter():
print('111')
yield
my_iter()
res = my_iter()
res.__next__() # 111
"""
多加一个__next__()会报错,因为执行一次代码会停在yield后面(类似鼠标的移动),如果想要执行yield后面的代码需要再加一个__next__()
"""
def my_iter():
print('111')
yield
print('222')
yield
print('333')
yield
res = my_iter()
res.__next__() # 111
res.__next__() # 222
res.__next__() # 333
"""
yield类似return,可以有返回值
"""
自定义生成器range()功能
1.my_range()中有两个参数
def my_range(start_num, end_num):
while start_num < end_num:
yield start_num
start_num += 1
for i in my_range(1, 10):
print(i)
2.my_range()中有一个参数
def my_range(start_num, end_num = None):
end_num = start_num
start_num = 0
while start_num < end_num:
yield start_num
start_num += 1
for i in my_range(10):
print(i) # 0-9
3.my_range()中有两个参数
def my_range(start_num, end_name, step=1):
while start_num < end_name:
yield start_num
start_num += step
for i in my_range(1, 10, 2):
print(i) # 1, 3, 5, 7, 9
yield冷门用法
如果yield后面有值,函数体代码会执行到yield行并且返回yield后面的值,如果yield前面有变量名和赋值符号,通过send给此变量名传值,调用一次相当于调用一次双下next
def eat(name, food=None):
print(f'{name}准备用餐')
while True:
food = yield
print(f'{name}正在吃{food}')
res = eat('jason') # 变成一个生成器
res.__next__() # 执行函数体代码
res.send('汉堡')
res.send('包子')
生成器表达式
列表生成式:
l1 = [i*3 for i in range(1, 10)]
print(l1) # [3, 6, 9, 12, 15, 18, 21, 24, 27]
元组生成器:组成一个新元组时直接打印变量名是一个内存地址,用for循环才能得到元组中的值
t1 = (i*3 for i in range(1, 10))
print(t1) # <generator object <genexpr> at 0x00000284A176F190>
for i in t1:
print(i)
"""
面试题:
"""
def add(n, i): # 1.普通函数 返回两个数的和 求和函数
return n + i
def test(): # 2.有yield关键字,定义生成器
for i in range(4):
yield i
g = test() # 3.激活生成器
for n in [1, 10]: # 4.第一次n=1 5.第二次n=10
g = (add(n, i) for i in g) # 5.第一次g = (add(1, i) for i in g)
# 6.g = (add(10, i) for i in (add(10, i) for i in g))
"""
第一次for循环
g = (add(n, i) for i in g)
第二次for循环
g = (add(10, i) for i in (add(10, i) for i in g))
"""
res = list(g) # 7.list(g)相当于for循环
print(res)
模块简介
1.py文件都可以道瑞或者被导入其他py文件,模块就是具有一定功能的py文件
2.python模块的历史: python刚开始的时候所有搞其他编程语言的程序员都看不起 甚至给python起了个外号>>>:调包侠(贬义词)
随着时间的发展项目的复杂度越来越高 上面那帮人也不得不用一下python 然后发现真香定律>>>:调包侠(褒义词)
3.python模块的表现形式:
3.1 py文件(py文件也可以称之为模块文件)
3.2 含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹存储)
3.3 已被编译为共享库或DLL的c或C++扩展(了解)
3.4 使用C编写并链接到python解释器的内置模块(了解)
模块的分类
1.自定义模块:我们自己写的模块
2.内置模块:python解释器提供的模块
3.第三方模块
导入模块的两种句式及优缺点
"""
重点:
1.首先要搞清楚执行文件和被执行文件,如果从文件1中调用了一个模块(文件2),那么文件2是被执行文件,文件1是执行文件
2.开发项目时py文件的名称一般是纯英文
3.导入模块文件(被执行文件)不需要填写后缀名
"""
1.import句式
以import a为例研究底层原理
1.1先产生执行文件的名称空间
1.2执行被导入文件的代码将产生的名字放入被导入文件的名称空间中
(name,age,函数名等)
1.3在执行文件的名称空间中产生一个模块的名字
1.4在该执行文件中使用该模块名点的方式使用模块名称空间中所有的名字(a.name;a.age,a.func()),a就是一个连接执行文件名称空间和模块名称空间的桥梁
"""
模块名称空间中的名字需要模块名点的方式才能使用,所以不会轻易改掉模块名称空间中的名字,需要改的话要将名字前加模块名点的方式。
"""
2.from...import...句式
以from a import name.func1为例研究底层原理
1.先产生执行文件的名称空间
2.执行被导入文件的代码将产生的名字放入导入文件的名称空间中
3.在执行文件的名称空间中产生对应的名字绑定模块名称空间对应的名字
4.在执行文件中直接使用名字就可以访问到名称空间中对应的名字
导入模块补充说明
1.起别名:
1.1给模块文件起别名
import bbb as b
print(b.name) # jason
1.2给模块名称空间中的名字起别名
from bbb import name as n
print(n) # jason
2.重复导入模块
解释器在导入某个模块时只会导入并且执行一次,后续如果重复导入这个模块就不会在执行了
3.涉及到多个模块导入
相似程度不高:
import aaa
import bbb
相似程度高:
import aaa, bbb
循环导入问题
两个文件彼此互相导入,并且互相导入对方的名字,极容易报错
解决方法:
1.应确保模块名称空间中的名字准备完毕(被执行文件的名字在调用模块之前)
2.应尽量避免循环导入发生
判断文件类型
1.所有py文件都可以打印__name__
1.1当py文件是执行文件时,在执行文件中执行print(__name_)_的结果是__main__
1.2当py文件是被执行文件时,并且在被执行文件中print(__name__)但不执行,在被导入文件中执行结果是被导入文件的文件名(不加后缀)
2.用from句式拿到被执行文件中的所有名字:
from aaa impore *
*可以拿到aaa中所有的名字,但是也可以在被执行文件中限制被拿到的名字:
__all__ = ['名字1', '名字2']
模块的查找顺序
1.内存:模块一经调用就会保存在内存当中,就算是删掉硬盘中的文件也能完成此次模块调用
2.内置:自定义模块尽量不要与内支模块冲突
3.系统环境变量
3.执行文件的sys.path(系统环境变量)
就看sys,path的第一个路径,如果sys.path第一个路径没有要找的模块文件,那么会直接报错
如果想不报错:
那么需要将c.py文件所在的路径添加到sys.path中,此时print(sys.path)会显示增加的c.py的目录路径,此时导入c模块就可以取到c内部的名字。
绝对导入和相对导入
"""
要分清导入文件和被导入文件
"""
1.绝对导入:就是按照文件路径一层层往下查找
from ddd.qwe import *
print(name) # max
2.相对导入:
.在路径中表示当前目录
..在路径中表示上一层目录
..\..在路径中表示上上一层目录
不在依据执行文件所在的sys.path 而是以模块自身路径为准
from . import b
相对导入只能用于模块文件中 不能在执行文件中使用
'''
相对导入使用频率较低 一般用绝对导入即可 结构更加清晰
'''
包
通俗来讲就是多个py文件的集合
专业定义:python2中内部含有init,py文件的文件夹,python3中北部含有py文件就叫包
包的导入使用
1.直接导入包名:导入包名就可以直接使用包下面_init_.py文件内的名字
import package
print(package.name) # jason
print(package.age) # 18
2.可以使用包下面文件内的名字
print(aaa.md1.age)
clooections模块
1.namedtuple:具名元组
from collections import namedtuple
point = namedtuple('坐标', ['x', 'y'])
p1 = point(1,6)
print(p1) # 坐标(x=1, y=6)
2.deque:双端队列
from collections import deque
list1 = deque(['max', 'jason'])
list1.appendleft('kitty')
print(list1) # deque(['kitty', 'max', 'jason'])
3.OrderDict:有序字典,先添加进去的键值对排序越靠前,会把每个键值对组成一个元组返回
from collections import OrderedDict
od = OrderedDict()
od['name'] = 'max'
od['age'] = 25
print(od)
6.Counter:计数器,将字符串中每个字符统计数量返回一个列表
from collections import Counter
s = 'jason'
print(Counter(s)) # Counter({'j': 1, 'a': 1, 's': 1, 'o': 1, 'n': 1})
time模块
1.time.time():时间戳
import time
print(time.time()) # 1666431189.0416696
2.结构化时间
import time
print(time.localtime())
3.格式化时间:是给人看的,连接符可以自定义,类似格式化输出
import time
print(time.strftime('%Y/%m/%d %H/%M/%S')) # 2022/10/22 20/36/20
print(time.strftime('%Y:%m:%d')) # 2022:10:22
print(time.strftime('%Y')) # 2022
datetime模块
1.datetime和date的区别在于date只能精确到日,datetime可以精确到秒
import datetime
print(datetime.datetime.now()) # 2022-10-22 20:52:24.980606
print(datetime.datetime.today()) # 2022-10-22 20:52:24.980607
print(datetime.date.today()) # 2022-10-22
2.获取utc时间,datetime.utcnow()
from datetime import datetime
print(datetime.utcnow()) # 2022-10-22 12:56:17.786613
print(datetime.now()) # 2022-10-22 20:56:17.786613 # 也可以直接用datetime.now()
3.通过5个数字获取时间(年月日时分),不能指定格式
from datetime import datetime
c = datetime(2021, 6, 8, 8, 50)
print(c) # 2021-06-08 08:50:00
4.获取指定格式历史时间
from datetime import datetime
print(datetime.strptime('2020年7月15日', '%Y年%m月%d日')) # 2020-07-15 00:00:00
from datetime import datetime
print(datetime.strptime('2015-6-6', '%Y-%m-%d')) # 2015-06-06 00:00:00
random模块
1.产生0-1的随机小数
import random
print(random.random()) # 0.15326039578465522
2.产生两位数之间的随机小数
import random
print(random.uniform(1,8)) # 5.044808278616509
3.产生两位数之间的随机整数(包含首尾)
import random
print(random.randint(1,6)) # 6
4.产生两位数之间随机整数,步长为2
import random
print(random.randrange(1, 10, 2)) # 1
5.列表中随机抽取一个元素,几率相等,choice不会保留数据类型只会弹出元素,choices会保留原数据类型
import random
print(random.choice(['max', 'jason', 'jerry'])) # jerry
print(random.choices(['max', 'jason', 'jerry'])) # ['max']
6.随机抽取多个元素,sample()括号内第二个元素指定抽取个数
import random
print(random.sample(['max', 'jason', 'jerry'], 2)) # ['jerry', 'jason']
7.打乱列表的顺序(洗牌):不用变量名赋值,不能直接打印
import random
a = [1,2,3,4,5,6,7,8,9,10,'J','Q','K']
random.shuffle(a)
print(a) # ['K', 'Q', 6, 4, 10, 7, 8, 3, 1, 2, 'J', 5, 9]
8.编写指定位数验证码:
import random
def index(n):
code = ''
for i in range(n):
upper = chr(random.randint(65, 90))
lower = chr(random.randint(97, 122))
num = str(random.randint(0, 9))
group = random.choice([upper, lower, num])
code += group
return code
res = index(4)
print(res) # 3bx1
os模块
1.os,mkdir():创建单层文件夹(目录)
import os
os.mkdir('a.txt')
"""
os.mkdir()只能创建单层目录,创建多层目录会报错
"""
2.os.makedirs():创建单层、多层文件夹(目录)
import os
os.makedirs(r'a/b/c')
os.makedirs(r'r')
3.os.rmdir()
可以删除单层空目录
import os
os.rmdir(r'a') # 可以删除单层目录,前提是目录下不能有其他文件夹或文件
多层文件只能删除一层,并且该目录只能是空目录
os.rmdir(r'a/b/c')
"""
如果c目录是空目录,只能删除c文件夹
"""
4.os.removedirs:删除多级目录,最后一级目录必须是空目录
os.removedirs(r'a/b')
os.removedirs(r'a/b/c')
5.os.listdir():展示括号内路径全部目录和文件,结果是一个列表(括号内可以是相对路径也可以是绝对路径)
print(os.listdir(r'D:\上海python金牌班\周总结2022.10.22 week04')) # ['.idea', 'a', 'aaa.py', 'bbb.py', 'ddd', 'package', '__pycache__', '周总结.py', '未命名.md']
6.os.getcwd():获取当前文件夹路径
print(os.getcwd()) # D:\上海python金牌班\周总结2022.10.22 week04
7.动态获取当前文件路径
print(os.path.abspath(__file__)) # D:\上海python金牌班\周总结2022.10.22 week04\周总结.py
8.动态获取当前目录(文件夹)路径
print(os.path.dirname(__file__)) # D:\上海python金牌班\周总结2022.10.22 week04
7.os.path.join():路径拼接
path1 = os.path.dirname(__file__)
print(os.path.join(path1, 'db')) # D:\上海python金牌班\周总结2022.10.22 week04\db
8.os.path.join():获取文件大小
print(os.path.getsize(r'a/a.txt'))
sys模块
1.获取当前目录
import sys
print(sys.path) # 返回结果是一个列表。列表中第一个路径和第二个路径和第二个路径是目录路径
2.获取解释器最大递归深度
import sys
print(sys.getrecursionlimit()) # 1000
3.获取解释器版本
import sys
print(sys.version)
4.获取平台信息
import sys
print(sys.platform) # win32
5.sys.argv:打印是一个列表,可以在cmd窗口中增加数据,并进行校验(路径中不能有中文)
import sys
res = sys.argv
if len(res) != 3:
print('请输入正确内容')
else:
username = res[1]
userpwd = res[2]
if username == 'max' and userpwd == '123':
print('登陆成功')
else:
print('用户名或密码错误')
json模块
1.json模块也称为序列化模块,序列化可以打破语言限制实现不同编程语言之间数据交互。python数据类型和JS中的自定义对象表现形式相同,但它们属于不同的语言,需要一个媒介来互相转换。将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化,相反的过程叫做反序列化
2.json格式数据的作用:实现不同语言的数据交互
3.json数据类型格式:字符串并且都是双引号
4.json相关操作
针对数据
json.dumps()
json.loads()
针对文件()
json.dump()
json.load()
5.将下列字典转换成json格式存储,并转换成正常格式读取:
import json
user_dict = {'user_name': 'max', 'user_age': 25, 'user_gender':'male'}
with open(r'a.txt', 'w', encoding='utf8') as f1:
res = json.dumps(user_dict)
f1.write(res)
with open(r'a.txt', 'r', encoding='utf8') as f2:
res1 = f2.read()
print(json.loads(res1))
"""
当json模块结合文件一起用时,可以将"序列化"、"写入"结合成一行代码:
json.dump(iser_dict. f1)
也可以将"反序列化"、"读"结合携程一行代码:
json.load(f2)
import json
user_dict = {'user_name': 'max', 'user_age': 25, 'user_gender':'male'}
with open(r'a.txt', 'w', encoding='utf8') as f1:
json.dump(user_dict, f1)
with open(r'a.txt', 'r', encoding='utf8') as f2:
res = json.load(f2)
print(res) # {'user_name': 'max', 'user_age': 25, 'user_gender': 'male'}
"""
软件开发目录规范
1.面条版阶段
所有的代码全部堆叠在一起
"""
第一个阶段可以看成是直接将所有的数据放在C盘
视频 音频 文本 图片
"""
2.函数版阶段
根据功能的不同封装不同的函数
"""
第二个阶段可以看成是将C盘下的数据分类管理
视频文件夹 音频文件夹 文本文件夹 图片文件夹
"""
3.模块版阶段
根据功能的不同拆分成不同的py文件
"""
第三个阶段可以看成是将C盘下的数据根据功能的不同划分到更合适的位置
系统文件夹 C盘
视频文件夹 D盘
图片文件夹 E盘
ps:类似于开公司(小作坊 小公司 上市公司)
为了资源的高效管理
"""
不是所有的文件都有bin文件夹
软件开发目录
目录规范主要规定开发程序过程中针对不同的文件功能需要做不同的分类
1.bin文件夹:主要存放项目启动文件(不是所有的文件都有bin文件夹);start.py
2.conf文件夹:主要存放项目配置文件;seetings.py,里面存放项目的默认配置 一般都是全大写
3.core文件夹:主要存放项目核心文件;src.py,里面存放项目核心功能
4.nterface文件夹:主要存放项目接口文件goods.py,user.py,account.py
5.db文件夹:主要存放项目相关数据:userinfo.txt
6.log文件夹:主要存放日志文件:log.log
7.lib文件夹:主要存放项目公共功能
8.readme文件:主要存放项目相关说明
9.requirements.txt文件:主要存放项目所需模块及文件
周末大作业
src文件代码:
import json
import os
is_login = 0
name = 0
shopping_car = {}
good_dict = {'1': ['挂壁面', 3], '2': ['印度飞饼', 22], '3': ['极品木瓜', 666], '4': ['土耳其土豆', 999],
'5': ['伊拉克拌面', 1000], '6': ['董卓戏张飞公仔', 2000], '7': ['仿真玩偶', 10000]}
new_dict = {}
def register():
now_path = os.path.dirname(__file__)
db_path = os.path.join(now_path, 'db')
if not os.path.exists(db_path):
os.mkdir(db_path)
user_name = input('请输入您的用户名>>>:').strip()
judge_name = f'{user_name}.json'
if judge_name in os.listdir(db_path):
print(f'用户{user_name}已注册')
return
name_path = os.path.join(db_path, judge_name)
user_pwd = input('请输入您的密码>>>:').strip()
user_dict = {'balance': 15000, 'shop_car': {}}
user_dict['username'] = user_name
user_dict['password'] = user_pwd
with open(name_path, 'w', encoding='utf8') as f1:
json.dump(user_dict, f1)
print(f'用户{user_name}注册成功')
def login():
global is_login, name
now_path = os.path.dirname(__file__)
db_path = os.path.join(now_path, 'db')
login_name = input('情输入您的用户名>>>:').strip()
judge_name = f'{login_name}.json'
if not judge_name in os.listdir(db_path):
print(f'用户{login_name}未注册')
return
name_path = os.path.join(db_path, judge_name)
login_pwd = input('请输入您的密码>>>:').strip()
with open(name_path, 'r', encoding='utf8') as f2:
login_dict = json.load(f2)
if login_name == login_dict.get('username') and login_pwd == login_dict.get('password'):
print(f'用户{login_name}登陆成功')
is_login = 1
name = login_name
print(is_login)
else:
print('登陆失败')
def shoppingcar():
global shopping_car
while True:
if is_login:
print(f"""
'1':挂壁面 价格:3
'2':印度飞饼 价格:22
'3':极品木瓜 价格:666
'4':土耳其土豆 价格:999
'5':伊拉克拌面 价格:1000
'6':董卓戏张飞公仔 价格:2000
'7':仿真玩偶 价格:10000
""")
choice = input('请输入您想购买的商品编号(q)>>>:').strip()
if choice == 'q':
return
if not choice in good_dict:
print('商品列表中暂无该商品')
continue
amount = input('请输入您想购买的数量>>>:').strip() # {'极品木瓜':[个数,单价]}
amount = int(amount) # amouct:整形
if not good_dict.get(choice)[0] in shopping_car: # good_dict = {'1':['挂壁面', 3] , '2':['印度飞饼', 22], '3':['极品木瓜', 666], '4':['土耳其土豆', 999], '5':['伊拉克拌面', 1000], '6':['董卓戏张飞公仔', 2000], '7':['仿真玩偶', 10000]}
shopping_car[good_dict[choice][0]] = [amount, good_dict.get(choice)[1]]
else:
new_amount = shopping_car.get(good_dict.get(choice)[0])[0]
new_amount += amount
shopping_car[good_dict[choice][0]] = [new_amount, good_dict.get(choice)[1]] # {'极品木瓜': [3, 666], '土耳其土豆': [4, 999], '伊拉克拌面': [5, 1000]}
else:
print('请先登录')
return
def seeshoppingcar():
print(shopping_car)
def balance(): # shopping_car = {'极品木瓜': [3, 666], '土耳其土豆': [4, 999], '伊拉克拌面': [5, 1000]}
global shopping_car
money = 0
for i in shopping_car:
shopping_money = shopping_car[i][0] * shopping_car[i][1]
money += shopping_money # money:得出购物车中的总商品一共需要多少钱
now_path = os.path.dirname(__file__)
db_path = os.path.join(now_path, 'db')
json_name = f'{name}.json'
name_path = os.path.join(db_path, json_name)
with open(name_path, 'r', encoding='utf8') as f3:
user_dict = json.load(f3) # user_dict = {'balance': 15000, 'shop_car': {}, 'username': 'max', 'password': '123'}
user_dict['shop_car'] = {}
rm_balance = user_dict.get('balance') - money
if rm_balance < 0:
print('您的余额不足,无法购买')
return
user_dict['balance'] = rm_balance
with open(name_path, 'w', encoding='utf8') as f4:
json.dump(user_dict, f4)
print(f'尊贵的{name}您好,您的购物车已结算')
shopping_car = {}
def rmshoppingcar():
global shopping_car
shopping_car = {}
print('您的购物车清空成功,现在里面什么都没有哦')
def account():
now_path = os.path.dirname(__file__)
db_path = os.path.join(now_path, 'db')
json_name = f'{name}.json'
name_path = os.path.join(db_path, json_name)
with open(name_path, 'r', encoding='utf8') as f5:
dict = json.load(f5)
ac = dict.get('balance')
print(f'您的余额为{ac}')
def recharge():
now_path = os.path.dirname(__file__)
db_path = os.path.join(now_path, 'db')
json_name = f'{name}.json'
name_path = os.path.join(db_path, json_name)
num = input('请输入您充值的金额>>>:').strip()
num = int(num)
with open(name_path, 'r', encoding='utf8') as f6:
dict = json.load(f6)
rm_num = dict.get('balance')
rm_num += num
dict['balance'] = rm_num
with open (name_path, 'w', encoding='utf8') as f7:
json.dump(dict, f7)
print(f'您的成功充值金额{num},您的账户余额为{rm_num}')
while True:
print("""
1.注册
2.登陆
3.加入购物车
4.查看购物车
5.结算购物车
6.清空购物车
7.查看余额
8.余额充值
""")
func_dict = {
'1': register,
'2': login,
'3': shoppingcar,
'4': seeshoppingcar,
'5': balance,
'6': rmshoppingcar,
'7': account,
'8':recharge
}
choice = input('请输入您的任务编号(q)>>>:').strip()
if choice == 'q':
print('欢迎下次光临')
break
if choice in func_dict:
func_dict.get(choice)()
else:
print('您输入的任务编号不存在')
python学习第四周总结的更多相关文章
- Python学习笔记基础篇——总览
Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...
- 2003031121-浦娟-python数据分析第四周作业-第二次作业
项目 内容 课程班级博客链接 20级数据班(本) 作业链接 Python第四周作业第二次作业 博客名称 2003031121-浦娟-python数据分析第四周作业-matolotlib的应用 要求 每 ...
- Python学习--04条件控制与循环结构
Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...
- Python学习--01入门
Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...
- Python 学习小结
python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...
- Python学习路径及练手项目合集
Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159
- python学习笔记-python程序运行
小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...
- Python学习记录day6
title: Python学习记录day6 tags: python author: Chinge Yang date: 2016-12-03 --- Python学习记录day6 @(学习)[pyt ...
- Python学习记录day5
title: Python学习记录day5 tags: python author: Chinge Yang date: 2016-11-26 --- 1.多层装饰器 多层装饰器的原理是,装饰器装饰函 ...
- [Python] 学习资料汇总
Python是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大且完善的通用型语言,已经有十多年的发展历史,成熟且稳定.Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用 ...
随机推荐
- 试试将.NET7编译为WASM并在Docker上运行
之前有听到说Docker支持Wasmtime了,刚好.NET7也支持WASM,就带大家来了解一下这个东西,顺便试试它怎么样. 因为WASM(WebAssembly) 一开始是一个给浏览器的技术,比起J ...
- 报错:com.mysql.jdbc.MysqlDataTruncation: Data truncation xxxx
报错 Out of range value for column 'pk' at row 1:表的字段长度不够 Data too long for column 'ip' at row 1:表的字段长 ...
- Inventor 2021保姆级安装教程
Inventor 2021 WIN10 64位安装步骤: 1.先使用"百度网盘客户端"下载INT21_CN_x64安装包到电脑磁盘里,并鼠标右击进行解压缩,安装前先断网,然后找到I ...
- Vscode连接gitee远程仓库
Git初始化项目 1. Git的基础配置 Git的安装配置 下载地址为:http://git-scm.com/downloads 安装完第一步要做的是,设置你的用户名和邮件地址. git config ...
- Spring Security(8)
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 之前虽然实现了角色和权限之间的简单配对,但是如果每一个角色都要重新来过一次,就有点呆板了.如果能够配置一个「角色模板」,再通过这个模板来配置其他 ...
- 【RocketMQ】主从模式下的消费进度管理
在[RocketMQ]消息的拉取一文中可知,消费者在启动的时候,会创建消息拉取API对象PullAPIWrapper,调用pullKernelImpl方法向Broker发送拉取消息的请求,那么在主从模 ...
- YonBuilder移动开发平台功能大盘点
YonBuilder是面向企业组织和个人开发者的低代码开发平台,实现无代码.低代码.专业代码开发三种模式.提供元数据驱动和画布构建两种开发方式,通过点击拖拽+自动化代码生成和移动多端编译的技术,与开放 ...
- 2022NewStarCTF新生赛一些比较有意思的题目wp
Misc_蚁剑流量分析 Pcap的文件可以直接使用工具 编辑器打开目录,一个一个看,可以找到eval危险函数 看到n3wst4r,直接使用linux正则匹配,找出相关内容 Url解码,了解一下蚁剑流量 ...
- JDBC的一些基础认识,写的不是特别完善,希望大家看的时候别太介意嘿嘿嘿
JDBC 1,概念和本质 Java DataBase Connectivity Java 数据库链接, Java语言操作数据库 JDBC的本质:是一套操作所有关系型数据库的规则(接口)而JDBC所有的 ...
- Kali-Linux-for-Docker
说明 基于kali官方开源的Docker镜像修改,如需使用官方固件可以前往https://hub.docker.com/r/kalilinux/kali-rolling Docker Hub http ...