一. 函数的嵌套
1. 函数的嵌套调用
定义:在电泳函数的过程中,调用的其他函数
1 #函数嵌套的调用 2 def max2(x,y): 3 if x > y: 4 return x 5 else: 6 return y 7 8 def max3(a,b,c,d): 9 res=max2(a,b) 10 res2=max2(res,c) 11 res3=max2(res2,d) 12 return res3 13 14 res=max3(1,2,3,4) 15 print(res) 16 17 #函数嵌套的定义: 18 def foo(): 19 def foo1(): 20 def foo2(): 21 def foo3(): 22 print('from foo3') 23 foo3() 24 foo2() 25 foo1() 26 foo()
二.名称空间和作用域
1. 名称空间:存放名字和变量值绑定关系的地方,有三种名称空间:内置名称空间,全局名称空间,局部名称空间。
内置名称空间:在python解释器启动时产生,存放一些python内置名字。
全局名称空间:在执行文件时产生,存放文件级别定义的名字。
局部名称空间:在执行文件过程中,如果调用了函数,则产生该函数的局部名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效。
名字的加载顺序是:内置====》全局 ====》局部
名字的查找顺序是:局部====》全局 ====》内置
2. 作用域:即作用范围
作用域关系是在函数定义阶段就已经固定,与函数的调用无关。
2.1 全局作用域:全局存活,全局有效(globals())
1 max=1111 2 def foo(): 3 def foo1(): 4 def foo2(): 5 def foo3(): 6 print(max) 7 foo3() 8 foo2() 9 foo1() 10 foo() 11 12 #global 在函数内引用全局变量,可以修改全局变量 13 x=1111 14 def foo(): 15 global x 16 x=100 17 def foo1(): 18 def foo2(): 19 def foo3(): 20 print(x) 21 foo3() 22 foo2() 23 foo1() 24 foo() 25 print(x)
2.2 局部作用域:临时存活,局部有效(locals())
1 x=111111111111111 2 def foo(): 3 def foo1(): 4 def foo2(): 5 x=100 6 def foo3(): 7 print(x) 8 foo3() 9 foo2() 10 foo1() 11 foo() 12 print(x)
2.3 查找作用域globals(),locals()及globals,nonlocal
1 #globals(),locals() 2 x=111111111 3 def foo(): 4 def f1(): 5 x=1 6 y=2 7 def f2(): 8 print(x,y) 9 print(globals()) #可以查看全局的作用域 10 print(locals()) #可以查看在函数内部的局部作用域 11 f2() 12 f1() 13 foo() 14 15 #global,nonlocal 16 x=111111111 17 def foo(): 18 def f1(): 19 global x #把全局变量引进函数内,可修改全局变量值,这个修改是全局有效 20 x=1 21 y=2 22 def f2(): 23 print(x,y) 24 f2() 25 f1() 26 foo() 27 print(x) 28 29 x=11111 30 def f1(): 31 def f2(): 32 x=1 33 y=2222 34 def f3(): 35 nonlocal x #只修改函数内部的变量值,局部有效 36 x=3 37 print(x) 38 f3() 39 f2() 40 f1() 41 print(x)
LEGB代表名字的查找顺序:locals----》enclosing function----》globals-----》__builtins__
locals 代表函数内的名字,包括局部变量和形参
enclosing function 外部嵌套函数的名字空间(闭包函数中比较常见)
__builtins__ 内置模块的名字空间
四. 闭包函数
闭包函数:定义在函数内部的函数,内部函数包含外部作用域而非全局作用域的引用。
闭包函数的应用:惰性计算,延迟计算
1 import requests #pip3 install requests 2 def get(url): 3 return requests.get(url) 4 5 def index(url): 6 def get(): 7 # return requests.get(url).text 8 print(requests.get(url).text) 9 return get 10 python_web=index('http://www.python.org') 11 print(python_web())
五.装饰器(闭包函数的一种应用场景)
装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象。
装饰器遵循的原则:1.不改变被装饰对象的源代码,2不修改被装饰对象的调用方式。
装饰器的目的:在遵循1和2 的原则情况下,为被装饰对象添加新功能。
装饰器名,必须写在被装饰对象的正上方,单独一行
1 import time 2 def timmer(func): 3 def warpper(*args,**kwargs): 4 statr_time=time.time() 5 res=func(*args,**kwargs) 6 stop_time=time.time() 7 print('%s'%(statr_time-stop_time)) 8 return res 9 return warpper 10 @timmer 11 def index(): 12 time.sleep(3) 13 print('welcome to index') 14 @timmer # home=timmer(home) 15 def home(): 16 time.sleep(2) 17 print('welcome to home page') 18 19 index() 20 home()
装饰器函数:wraps
1 import time 2 from functools import wraps 3 def timmer(func): 4 @wraps(func) 5 def warpper(*args,**kwargs): 6 statr_time=time.time() 7 res=func(*args,**kwargs) 8 stop_time=time.time() 9 print('%s'%(statr_time-stop_time)) 10 return res 11 return warpper 12 @timmer 13 def index(): 14 '''这是测试''' 15 time.sleep(3) 16 print('welcome to index') 17 @timmer # home=timmer(home) 18 def home(): 19 time.sleep(2) 20 print('welcome to home page') 21 22 print(index.__doc__) 23 print(help(index))
多装饰器:一个函数可以有多个函数
1 import time 2 from functools import wraps 3 current_user={'user':None} 4 5 def timmer(func): 6 @wraps(func) 7 def wrapper(*args,**kwargs): 8 start=time.time() 9 res=func(*args,**kwargs) 10 stop=time.time() 11 print('run time is %s' %(stop-start)) 12 return res 13 return wrapper 14 def auth(auth_type='file'): 15 def deco(func): 16 def wrapper(*args, **kwargs): 17 if auth_type == 'file': 18 if current_user['user']: 19 return func(*args, **kwargs) 20 name = input('name: ').strip() 21 password = input('password: ').strip() 22 23 with open('db.txt', encoding='utf-8') as f: 24 user_dic = eval(f.read()) 25 if name in user_dic and password == user_dic[name]: 26 res = func(*args, **kwargs) 27 current_user['user'] = name 28 return res 29 else: 30 print('user or password error') 31 elif auth_type == 'mysql': 32 print('mysql') 33 34 elif auth_type == 'ldap': 35 print('ldap') 36 else: 37 print('not valid auth_type') 38 return wrapper 39 return deco 40 41 42 #多装饰器 43 @timmer #index=timmer(wrapper) 44 @auth() # @deco #index=deco(index) #wrapper 45 def index(): 46 '''这是index函数''' 47 time.sleep(3) 48 print('welcome to index') 49 return 123 50 51 # print(index.__doc__) 52 # print(help(index)) 53 54 index()
六.装饰器练习
1 一:编写函数,(函数执行的时间是随机的) 2 二:编写装饰器,为函数加上统计时间的功能 3 三:编写装饰器,为函数加上认证的功能 4 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 5 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式 6 五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录 7 六:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果 8 七:为题目五编写装饰器,实现缓存网页内容的功能: 9 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中 10 扩展功能:用户可以选择缓存介质/缓存引擎,针对不同的url,缓存到不同的文件中 11 八:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作 12 九 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定 13 注意:时间格式的获取 14 import time 15 time.strftime('%Y-%m-%d %X')
1 # 一:编写函数,(函数执行的时间是随机的) 2 import time 3 def index(): 4 time.sleep(3) 5 print('welcome to index') 6 # 二:编写装饰器,为函数加上统计时间的功能 7 import time 8 def timmer(func): 9 def wapepr(*args,**kwargs): 10 start_time=time.time() 11 res=func(*args,**kwargs) 12 stop_time=time.time() 13 print('%s'%(stop_time-start_time)) 14 return res 15 return wapepr 16 @timmer 17 def index(): 18 time.sleep(3) 19 print('welcome to index') 20 index() 21 # 三:编写装饰器,为函数加上认证的功能 22 import time 23 current_user={'user':None} 24 def authen(func): 25 def user_authen(*args,**kwargs): 26 if current_user['user']: 27 return func(*args,**kwargs) 28 name=input('请输入名字:').strip() 29 password=input('请输入密码:').strip() 30 with open('db.txt','r',encoding='utf-8') as f: 31 user_dic=eval(f.read()) 32 if name in user_dic and user_dic[name] == password: 33 print('登录成功') 34 current_user['user']=name 35 res=func(*args,**kwargs) 36 return res 37 else: 38 print('用户名或密码错误!') 39 return user_authen 40 @authen 41 def home(): 42 time.sleep(2) 43 print('welcome to home page') 44 45 @authen 46 def index(): 47 time.sleep(3) 48 print('welcome to index') 49 index() 50 home() 51 # 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 52 # 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式 53 import time 54 current_user={'user':None} 55 def authen(func): 56 def user_authen(*args,**kwargs): 57 if current_user['user']: 58 return func(*args,**kwargs) 59 name=input('请输入名字:').strip() 60 password=input('请输入密码:').strip() 61 with open('db.txt','r',encoding='utf-8') as f: 62 user_dic=eval(f.read()) 63 if name in user_dic and user_dic[name] == password: 64 print('登录成功') 65 current_user['user']=name 66 res=func(*args,**kwargs) 67 return res 68 else: 69 print('用户名或密码错误!') 70 return user_authen 71 @authen 72 def home(): 73 time.sleep(2) 74 print('welcome to home page') 75 76 @authen 77 def index(): 78 time.sleep(3) 79 print('welcome to index') 80 index() 81 home() 82 # 五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录 83 import time 84 def timmer(func): 85 def wraps(*args,**kwargs): 86 s1=time.time() 87 res=func(*args,**kwargs) 88 s2=time.time() 89 print('%s'%(s2-s1)) 90 current_user={'user':None,'logintime':None,'timeout':0.000003} 91 def authen(func): 92 def user_authen(*args,**kwargs): 93 if current_user['user']: 94 tomeout=time.time()-current_user['logintime'] 95 if tomeout < current_user['timeout']: 96 return func(*args,**kwargs) 97 name=input('请输入名字:').strip() 98 password=input('请输入密码:').strip() 99 with open('db.txt','r',encoding='utf-8') as f: 100 user_dic=eval(f.read()) 101 if name in user_dic and user_dic[name] == password: 102 print('登录成功') 103 current_user['user']=name 104 current_user['logintime']=time.time() 105 res=func(*args,**kwargs) 106 return res 107 else: 108 print('用户名或密码错误!') 109 return user_authen 110 @authen 111 def home(): 112 time.sleep(2) 113 print('welcome to home page') 114 115 @authen 116 def index(): 117 time.sleep(3) 118 print('welcome to index') 119 index() 120 home() 121 # 六:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果 122 import requests 123 def index(url): 124 def get(): 125 # return requests.get(url).text 126 print(requests.get(url).text) 127 return get 128 web=index('http://www.python.org') 129 web() 130 # 七:为题目五编写装饰器,实现缓存网页内容的功能: 131 # 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中 132 import requests 133 import os 134 cache_file='cache.txt' 135 def make_cache(func): 136 def wrapper(*args,**kwargs): 137 if not os.path.exists(cache_file): 138 with open(cache_file,'w'):pass 139 140 if os.path.getsize(cache_file): 141 with open(cache_file,'r',encoding='utf-8') as f: 142 res=f.read() 143 else: 144 res=func(*args,**kwargs) 145 with open(cache_file,'w',encoding='utf-8') as f: 146 f.write(res) 147 return res 148 return wrapper 149 150 @make_cache 151 def get(url): 152 return requests.get(url).text 153 154 155 # res=get('https://www.python.org') 156 157 # print(res) 158 # 扩展功能:用户可以选择缓存介质/缓存引擎,针对不同的url,缓存到不同的文件中 159 import requests,os,hashlib 160 engine_settings={ 161 'file':{'dirname':'./db'}, 162 'mysql':{ 163 'host':'127.0.0.1', 164 'port':3306, 165 'user':'root', 166 'password':'123'}, 167 'redis':{ 168 'host':'127.0.0.1', 169 'port':6379, 170 'user':'root', 171 'password':'123'}, 172 } 173 174 def make_cache(engine='file'): 175 if engine not in engine_settings: 176 raise TypeError('egine not valid') 177 def deco(func): 178 def wrapper(url): 179 if engine == 'file': 180 m=hashlib.md5(url.encode('utf-8')) 181 cache_filename=m.hexdigest() 182 cache_filepath=r'%s/%s' %(engine_settings['file']['dirname'],cache_filename) 183 184 if os.path.exists(cache_filepath) and os.path.getsize(cache_filepath): 185 return open(cache_filepath,encoding='utf-8').read() 186 187 res=func(url) 188 with open(cache_filepath,'w',encoding='utf-8') as f: 189 f.write(res) 190 return res 191 elif engine == 'mysql': 192 pass 193 elif engine == 'redis': 194 pass 195 else: 196 pass 197 198 return wrapper 199 return deco 200 201 @make_cache(engine='file') 202 def get(url): 203 return requests.get(url).text 204 205 # print(get('https://www.python.org')) 206 print(get('https://www.baidu.com')) 207 # 八:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作 208 route_dic={} 209 def make_route(name): 210 def deco(func): 211 route_dic[name]=func 212 return deco 213 @make_route('select') 214 def func1(): 215 print('select') 216 @make_route('insert') 217 def func2(): 218 print('insert') 219 @make_route('update') 220 def func3(): 221 print('update') 222 print(route_dic) 223 # 九 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定 224 # 注意:时间格式的获取 225 # import time 226 # time.strftime('%Y-%m-%d %X') 227 import time 228 import os 229 230 def logger(logfile): 231 def deco(func): 232 if not os.path.exists(logfile): 233 with open(logfile,'w'):pass 234 235 def wrapper(*args,**kwargs): 236 res=func(*args,**kwargs) 237 with open(logfile,'a',encoding='utf-8') as f: 238 f.write('%s %s run ' %(time.strftime('%Y-%m-%d %X'),func.__name__)) 239 return res 240 return wrapper 241 return deco 242 243 @logger(logfile='a.log') 244 def index(): 245 print('index') 246 247 index()
七.迭代器
迭代的概念:重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果就是下一次迭代的初始值。
可迭代对象有:
s='hello' l=['a','b','c','d'] t=('a','b','c','d') dic={'name':'egon','sex':'m',"age":18} set1={1,2,3} f=open('db.txt') s.__iter__() l.__iter__() t.__iter__() dic.__iter__() set1.__iter__() f.__iter__()
迭代器:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器。
迭代器对象:1.有__iter__方法,执行得到的结果仍是迭代本身,2.有__next__方法。
dic={'name':'egon','sex':'m',"age":18} i=dic.__iter__() print(i) #iterator迭代器 #i.__next__() #next(i) print(next(i)) print(next(i)) print(next(i)) print(next(i)) #StopIteration
不依赖于索引的取值方法:
l=['a','b','c','d'] dic={'name':'egon','sex':'m',"age":18} iter_l=iter(l) iter_dic=iter(dic) while True: try: # print(next(iter_l)) k=next(iter_dic) print(k,dic[k]) except StopIteration: break
迭代器的优点:
1. 提供了一种不依赖索引的取值方法。
2. 迭代器本身,比其他数据类型更省内存(一次只有一行数据在内存)。
1 l=['a','b','c','d'] 2 i=iter(l) 3 4 dic={'a':1,'b':2} 5 x=dic.keys() 6 print(x) 7 i=x.__iter__() 8 9 with open('a.txt') as f: 10 print(next(f),end='') 11 print(next(f),end='') 12 print(next(f),end='') 13 f.read()
迭代器的缺点:
1. 一次性,只能向前,不能回退,不如索引取值方便。
2. 无法预知什么时候取值结束,即无法预知长度。
for 循环原理,就是迭代循环
1 l=['a','b','c','d'] 2 for item in l: #iter_l=l.__iter__() 3 print(item) 4 5 for item in {1,2,3,4}: 6 print(item) 7 8 with open('a.txt') as f: 9 # for line in f: #i=f.__iter__() 10 # print(line) 11 print(f is f.__iter__())
判断可迭代对象与迭代器对象
1 from collections import Iterable,Iterator 2 s='hello' 3 l=['a','b','c','d'] 4 t=('a','b','c','d') 5 dic={'name':'egon','sex':'m',"age":18} 6 set1={1,2,3} 7 f=open('a.txt') 8 9 print(isinstance(s,Iterable)) #判断是否是可迭代对象 10 print(isinstance(l,Iterable)) 11 print(isinstance(t,Iterable)) 12 print(isinstance(dic,Iterable)) 13 print(isinstance(set1,Iterable)) 14 print(isinstance(f,Iterable)) 15 16 print(isinstance(s,Iterator)) #判断是否是迭代器对象 17 print(isinstance(l,Iterator)) 18 print(isinstance(t,Iterator)) 19 print(isinstance(dic,Iterator)) 20 print(isinstance(set1,Iterator)) 21 print(isinstance(f,Iterator))
八. 生成器
生成器:在函数内部包含yield关键,那么函数执行的结果就是生成器。
yield的功能:
1.把函数的结果做成生成器(以一种优雅的方式封装__iter__,__next__)
2. 函数的暂停及再继续运行状态是由yield控制。
1 def func(): 2 print('first') 3 yield 11111111 4 print('second') 5 yield 2222222 6 print('third') 7 yield 33333333 8 print('fourth') 9 10 11 g=func() 12 print(g) 13 from collections import Iterator 14 print(isinstance(g,Iterator)) 15 16 print(next(g)) 17 print('======>') 18 print(next(g)) 19 print('======>') 20 print(next(g)) 21 print('======>') 22 23 for i in g: #i=iter(g) 24 print(i)
yield 和return的比较
相同:都有返回值的功能
不同:return只能返回一次值,yield可以返回多次值
应用一:
1 def my_range(start,stop): 2 while True: 3 if start == stop: 4 raise StopIteration #遇到StopIteration 结束 5 yield start #2 6 start+=1 #3 7 8 g=my_range(1,3) 9 # print(next(g)) 10 # print(next(g)) 11 # print(next(g)) 12 13 for i in my_range(1,5): 14 print(i)
应用二:管道 tailf access.log|grep 'error'
1 import time 2 def tailf(filepath): 3 with open(filepath,'r',encoding='utf-8') as f: 4 f.seek(0, 2) 5 while True: 6 line=f.readline() 7 if line: 8 yield line 9 else: 10 time.sleep(0.2) 11 12 def grep(pattern,lines): 13 for line in lines: 14 if pattern in line: 15 print(line,end='') 16 17 grep('error',tailf('access.log'))
九. 三元表达式,列表推导式,生成器表达式
1. 三元表达式
1 def foo(x): 2 if x > 3: 3 return 'ok' 4 else: 5 return 'no' 6 7 x=10 8 res=x if x > 3 else 'no' 9 print(res) 10 11 def max2(x,y): 12 return x if x > y else y 13 print(max2(1,3)) 14 15 name='egon' 16 print('SB' if name == 'alex' else 'shuai')
2. 列表推导式
1 #------------------1:引子 2 #生一筐鸡蛋 3 egg_list=[] 4 for i in range(10): 5 egg_list.append('鸡蛋%s' %i) 6 print(egg_list) 7 8 #列表解析 9 egg_list=['鸡蛋%s' %i for i in range(10)] 10 print(egg_list) 11 12 #列表内每个数的2倍生成一个新列表 13 nums = [1, 2, 3, 4, 5, 6] 14 nums_new=[] 15 for i in nums: 16 nums_new.append(i**2) 17 print(nums_new) 18 19 #列表解析大于3的数的2倍生成一个新列表 20 nums_new=[i**2 for i in nums if i > 3 ] 21 print(nums_new)
3. 生成器表达式
1 g=('egg%s' %i for i in range(1000)) 2 print(g) 3 print(next(g)) 4 print(next(g)) 5 print(next(g)) 6 7 with open('a.txt',encoding='utf-8') as f: 8 # res=max((len(line) for line in f)) 9 res=max(len(line) for line in f) 10 print(res) 11 # 12 print(max([1,2,3,4,5,6])) 13 14 with open('a.txt',encoding='utf-8') as f: 15 g=(len(line) for line in f) 16 print(max(g)) 17 print(max(g))
4.声明式编程应用
1 res=sum(i for i in range(3)) 2 print(res) 3 4 with open('db.txt',encoding='utf-8') as f: 5 l=(float(line.split()[1])*int(line.split()[2]) for line in f) 6 print(sum(l)) 7 8 l=[] 9 for line in f: 10 goods=line.split() 11 price=float(goods[1]) 12 count=int(goods[2]) 13 cost=price * count 14 l.append(cost) 15 16 print(sum(l)) #196060.0 17 18 # [{'name': 'apple', 'price': 333, 'count': 3}, ] 19 with open('db.txt',encoding='utf-8') as f: 20 info=[{'name':line.split()[0], 21 'price':float(line.split()[1]), 22 'count':int(line.split()[2])} for line in f if float(line.split()[1]) >= 30000] 23 print(info)
十. 作业
模拟实现一个ATM+购物商城程序
1 额度 15000或自定义 2 实现购物商城,买东西加入 购物车,调用信用卡接口结账 3 可以提现,手续费5% 4 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息 5 支持多账户登录 6 支持账户间转账 7 记录每月日常消费流水 8 提供还款接口 9 ATM记录操作日志 10 提供管理接口,包括添加账户、用户额度,冻结账户等。。。 11 用户认证用装饰器
1 # 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账 2 #商品菜单 3 goods_info_dic = {} 4 def menu(): 5 with open('db.txt', 'r', encoding='utf-8') as f: 6 goods_dic = eval(f.read()) 7 i = 0 8 for item in goods_dic: 9 goods_info_dic[i] = {'name': item, 'price': goods_dic[item], 'nums': 1} 10 i += 1 11 print('以下是所有商品信息'.center(38, '*')) 12 for line in goods_info_dic: 13 print('商品编号: ', line, ' name:', goods_info_dic[line]['name'], ' price: ¥', goods_info_dic[line]['price']) 14 #加入购物车 15 user_goods=[] 16 def googs(): 17 if current_user['user']: 18 menu() 19 count=input('请输入商品编号:').strip() 20 if count.isdigit(): 21 count=int(count) 22 if count < len(goods_info_dic): 23 if count not in user_goods: 24 user_goods.append(count,user_goods[count]) 25 else: 26 pass 27 menu() 28 count=input('请输入商品编号:').strip() 29 if count.isdigit(): 30 count=int(count) 31 if count < len(goods_info_dic): 32 if count not in user_goods: 33 user_goods[count]=goods_info_dic[count] 34 else: 35 user_goods[count]['nums']+=1 36 mun = input('请输入购买商品的数量:').strip() 37 if mun.isdigit(): 38 if user_goods[count]['nums'] == 1: 39 user_goods[count]['nums'] = int(mun) 40 else: 41 user_goods[count]['nums'] = int(mun) 42 print('购物车里的商品:',user_goods) 43 44 45 def home(): 46 time.sleep(2) 47 print('welcome to home page') 48 49 # 5.支持多账户登录 50 import time 51 current_user={'user':None} 52 def authen(func): 53 def user_authen(*args,**kwargs): 54 if current_user['user']: 55 return func(*args,**kwargs) 56 name=input('请输入名字:').strip() 57 password=input('请输入密码:').strip() 58 with open('user','r',encoding='utf-8') as f: 59 user_dic=eval(f.read()) 60 if name in user_dic and user_dic[name] == password: 61 print('登录成功') 62 current_user['user']=name 63 res=func(*args,**kwargs) 64 return res 65 else: 66 print('用户名或密码错误!') 67 return user_authen 68 # 6.支持账户间转账 69 # 7.记录每月日常消费流水 70 # 8.提供还款接口 71 # 9.ATM记录操作日志 72 # 10.提供管理接口,包括添加账户、用户额度,冻结账户等。。。 73 # 11.用户认证用装饰器