博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python全栈开发 * 12 知识点汇总 * 180530
阅读量:6137 次
发布时间:2019-06-21

本文共 10284 字,大约阅读时间需要 34 分钟。

12  知识点总结  装饰器进阶
⼀. 通⽤装饰器的回顾 1.开闭原则:  对增加功能开放. 对修改代码封闭 2.装饰器的作⽤:  在不改变原有代码的基础上给⼀个函数增加功能 3.通⽤装饰器的写法: def wrapper(fn):     def inner(*args,**kwargs):         print("目标函数前一行")         ret=fn(*args,**kwargs)         print("目标函数后一行")         return ret     return inner @wrapper def target_func(*args,**kwargs):     print("我是目标函数体") target_func() 4.执⾏过程: (1) 程序从上向下, 当执⾏到@wrapper的时候. 把函数作为参数传递给wrapper函数. 得到inner函数. 重新赋值给target_func   (2) 当执⾏到target_func的时候. 我们实际上执⾏的是inner函数. inner函数会先执⾏⽬标函数之前的代码. 然后再执⾏你的⽬标函数. 执⾏完⽬标函数最后执⾏的是⽬标函数     之后的代码  ⼆. 函数的有⽤信息 1. 如何给函数添加注释     用三个引号来表示 def eat(food,drink):     """  eat:把传递进来的吃掉     :param food: 参数food是什么意思     :param drink: 参数drink是什么意思     :return: None   返回什么     """     print(food,drink)     return "very good"   按住ctrl 点内置函数名,可以查看函数的注释如int,str 等 2.如何获取到函数的相关信息 def eat(food,drink):     """     :param food: 参数food是什么意思     :param drink: 参数drink是什么意思     :return: None   返回什么     """     print(food,drink)     # print(eat.__name__)     读取不出来     # print(eat.__doc__)      读取不出来     return "very good" eat("水果","可乐") print(eat.__name__)       # 查询函数名 print(eat.__doc__)        #查询函数文档注释   函数名.__name__可以查看函数的名字 (双下划线)   函数名.__doc__ 可以查看函数的⽂档注释 (1) 一个被装饰器装饰过的函数:查询目标函数的函数名 def wrapper(fn):     def inner(*args,**kwargs):    #  聚合         print("目标函数前一行")         ret=fn(*args,**kwargs)    #  打散  这⾥的作⽤. 其实就是为了保证我可以装饰所有函数⽽准备的         print("目标函数后一行")         return ret     return inner @wrapper def target_func(*args,**kwargs):      print("我是目标函数体") target_func() print(target_func.__name__)         #    被装饰过的函数函数名是inner. (2) 把上述查询函数名修改为原函数名 from functools import wraps       #    加   引入函数模块 def wrapper(fn):     @wraps(fn)                      #    加   使用函数原来的名字     def inner(*args,**kwargs):         print("目标函数前一行")         ret=fn(*args,**kwargs)         print("目标函数后一行")         return ret     return inner @wrapper def target_func(*args,**kwargs):      print("我是目标函数体") target_func() print(target_func.__name__)         #    查询结果不再是inner  而是target_func @wrapper def new_target_func():  print("我是另⼀个⽬标函数") new_target_func() print(new_target_func.__name__) 三.装饰器传参 def wrapper_out(flag):     def wrapper(fn):         def inner(*args,**kwargs):             if flag==True:                #     设定条件,满足执行下一步                 print("目标函数前一行")                 ret=fn(*args,**kwargs)                 print("目标函数后一行")             else:                         #      不满足执行这一步                 ret=fn(*args,**kwargs)             return ret         return inner     return wrapper @wrapper_out(True) def target_func():     print("我是目标函数体") target_func()                        #   目标函数前一行,我是目标函数体,目标函数后一行 @wrapper_out(False) def target_func():     print("我是目标函数体") target_func()                        #   我是目标函数体 执行步骤: 先执⾏wrapper(True)  然后再@返回值. 返回值恰好是wrapper. 结果就是@wrapper 四.多个装饰器装饰一个函数 def wrapper(fn):     def inner(*args,**kwargs):         print("我是a")         ret=fn(*args,**kwargs)         print("我是b")         return ret     return inner def wrapper1(fn):     def inner(*args,**kwargs):         print("我是c")         ret=fn(*args,**kwargs)         print("我是d")         return ret     return inner def wrapper2(fn):     def inner(*args,**kwargs):         print("我是e")         ret=fn(*args,**kwargs)         print("我是f")         return ret     return inner @wrapper2 @wrapper1 @wrapper def eat(*args,**kwargs):     print("我是目标函数") eat() 执行步骤: 执⾏顺序: ⾸先@wrapper1装饰起来. 然后获取到⼀个新函数是wrapper1中的inner. 然后执⾏@wrapper2.这个时候. wrapper2装饰的就是wrapper1中的inner. 第⼆层装饰器前(第⼀层装饰器前(⽬标)第⼀层装饰器后)第⼆层装饰器后. 程序从左到右执⾏ 五.补充知识点
1枚举 (同时拿元素和索引) lst=["金","木","水","火","土"] for index,element in enumerate(lst):     print(index,element)          #  解构 for element in enumerate(lst):     print(element)                #  结果是元组(0,"金) 2.存盘 , 网络传输 s="提前祝大家端午节快乐" bys=s.encode("UTF-8")             # 编码 print(bys)                        # 结果 字节 s1=bys.decode("UTF-8")            # 解码 print(s1)                         # 结果 字符串  应用:  把UTF-8 转成 GBK bys=b'\xe6\x8f\x90'               # 一个字符的utf-8 形式 s=bys.decode("UTF-8")             # 用UTF-8 解码成 字符串s gbk=s.encode("GBK")               # 再把字符串转化成GBK (两个字节) print(gbk)                        # 结果 b'\xcc\xe1'
作业:

1.给每个函数写一个记录日志的功能,功能要求:每一次调用函数之前,要将函数名称,时间节点记录到log的日志中

所需模块

import time

struct_time = time.localtime()    

# localtime() : localtime是 把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地时间

print(time.strftime("%Y-%m-%d %H:%M:%S",struct_time))

# strftime是一种,根据格式化本地时间/日期,函数的功能将时间格式化,或者说格式化一个时间字符串

 

import time struct_time = time.localtime() print(time.strftime("%Y-%m-%d %H:%M:%S",struct_time)) import time def wrapper(fn):     def inner(*args,**kwargs):         struct_time = time.localtime()    #时间         f=open("log",mode="a",encoding="UTF-8")  # 文件         f.write(fn.__name__+"\t"+time.strftime("%Y-%m-%d %H:%M:%S", struct_time)+"\n")    #文件名和和格式化后的时间添加到文件中         ret=fn(*args,**kwargs)# 目标函数         return ret     return inner @wrapper def func1(*args,**kwargs):     print("函数一") func1() 2.京东,淘宝登陆系统
# 1,用户有两套账号密码,一套为京东账号密码,一套为淘宝账号密码分别保存在两个文件中。    # 2,设置四个函数,分别代表 京东首页,京东超市,淘宝首页,淘宝超市。    # 3,启动程序后,呈现用户的选项为:    #  1,京东首页    #  2,京东超市    #  3,淘宝首页    #  4,淘宝超市    #  5,退出程序    # 4,四个函数都加上认证功能,用户可任意选择,用户选择京东超市或者京东首页,只要输入一次京东账号和密码并成功,则这两个函数都可以任意访问;  # 用户选择淘宝超市或者淘宝首页,只要输入一次淘宝账号和密码并成功,则这两个函数都可以任意访问. flag1 = True flag2 = True def wrapper_out(aaa):     def wrapper(fn):         def inner(*args,**kwargs):             flag = True             global flag1,flag2             if aaa=="jd" :                 while flag and flag1==True:                     user=input("请输入您的用户名:")                     pwd=input("请输入您的密码:")                     with open("jd-user",mode="r",encoding='utf-8')as f:                         for i in f.readlines():                             username,password=i.strip().split(",")                             if user==username and pwd==password:                                 print("登陆成功")                                 flag = False                                 flag1 = False                                 break                             else:                                 print("登陆失败")             elif aaa=="tb":                 while flag and flag2==True:                     user2=input("请输入您的用户名:")                     pwd2=input("请输入您的密码:")                     with open("tb_user",mode="r",encoding="utf-8")as f:                         for i in f.readlines():                             username2,password2=i.strip().split(",")                             if user2==username2 and pwd2==password2:                                 print("登陆成功")                                 flag=False                                 flag2=False                                 break                             else:                                 print("登陆失败")             ret=fn()             return ret         return inner     return wrapper @wrapper_out("jd") def jd_index():     print("京东首页") @wrapper_out("jd") def jd_market():     print("京东超市") @wrapper_out("tb") def tb_index():     print("淘宝首页") @wrapper_out("tb") def tb_market():     print("淘宝超市") def logout():     print("退出程序")     global flag1, flag2     flag1=False     flag2=False def start():     with open("菜单",mode="r",encoding="utf-8")as f:         for line in f:             print(line.strip()) def choic():     while 1:         choose=input("请输入序号;")         if choose=="1":             jd_index()         elif choose=="2":             jd_market()         elif choose=="3":             tb_index()         elif choose=="4":             tb_market()         elif choose=="5":             logout()             flag=False start() choic() 3.明星投票系统:
# 1. ⽤户注册. 将⽤户名和密码保存在⽂件中. # 2. 登录功能. 不需要三次登录. 正常反复⽆限登录就可以. 直到登录成功为⽌ # 3. ⽤户登录后可以查看所有明星信息. 明星信息保存在明星⽂件中. #  例如: #  1 林俊杰 1 #  2 周杰伦 0 #  3 ⿇花藤 0 #  第⼀位是序号, 第⼆位是名字, 第三位是得票数 # 4. 给明星进⾏投票 # 5. 每个⼈每24⼩时只能投⼀次票(扩展功能, 装饰器) #  思路: 每次⽤户投票之后. 都从⽂件中查询⼀下⽤户上⼀次投票时间. 让⽤户上⼀ # 次投票时间和当前系统时间做时间差. 如果⼤于24⼩时. 则可以进⾏投票. 如果⼩于24⼩时, # 则提⽰⽤户不能进⾏投票. 时间处理请⾃⾏百度. #  使⽤知识点: #  1. 函数, 请将以上功能尽可能的封装成函数. ⽤函数来描述每⼀个功能是我们以后开发 # 经常使⽤的⼀种写法和思路 import os import time def wrapper(fn):     def inner():         t = time.time()         t2 = os.path.getmtime("stra_info")         if t - t2 <86400.0:             print('24小时内不要重复登陆')             return         ret=fn()         return ret     return inner def start():     with open("main",mode="r",encoding="utf-8")as f:         for line in f.readlines():             print(line.strip()) start() def regist():     with open("user_info",mode="r+",encoding="utf-8")as f1:         for i in f1.readlines():             user=input("请输入用户名:")             pad=input("请输入密码:")             if user==i.strip().split(",")[0]:                 print("该用户名已存在")             else:                 with open("user_info",mode="a",encoding="utf-8")as f2:                     f2.write("\n"+user+","+pad)                     print("注册成功")                     return # regist() def logon ():     while 1:         username1 = input("请输入用户名:")         password1 = input("请输入密码:")         with open("user_info",mode="r",encoding="utf-8")as f3:             for i in f3.readlines():                 user1,pwd1=i.strip().split(',')                 if username1==user1 and password1==pwd1:                     print("登陆成功")                     return             else:                 print("登陆失败请重新登陆") # logon() def star_info():     with open("star_info", mode="r",encoding="utf-8")as f4:         for line in f4.readlines():             print(line.strip()) @wrapper def vote():     vote_num=input('请输入明星id:')     with open("stra_info",mode="r",encoding="utf-8")as f5,open("star_info1",mode="w",encoding="utf-8")as f6:         for line in f5.readlines():             num,name,poll=line.strip().split(" ")             if vote_num==num:                 f6.write(num+" "+name+" "+str(int(num)+1)+'\n')             else:                 f6.write(line)     os.remove("stra_info")     os.rename("star_info1","stra_info") def logout():     print('您已退出系统') def choice():     while 1:         choose=input('请输入项目序号:')         if choose=="1":             regist()         elif choose=="2":             logon()         elif choose=="3":             star_info()         elif choose=="4":             vote()         elif choose=="5":             logout() start() choice()
 
 

 

 
 

转载于:https://www.cnblogs.com/J-7-H-2-F-7/p/9187974.html

你可能感兴趣的文章
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>
直播视频流技术名词
查看>>
企业级java springboot b2bc商城系统开源源码二次开发-hystrix参数详解(八)
查看>>
java B2B2C 多租户电子商城系统- 整合企业架构的技术点
查看>>
IOC —— AOP
查看>>
比特币现金将出新招,推动比特币现金使用
查看>>
数据库的这些性能优化,你做了吗?
查看>>
某大型网站迁移总结(完结)
查看>>
mysql的innodb中事务日志(redo log)ib_logfile
查看>>
部署SSL证书后,网页内容造成页面错误提示的处理办法
查看>>
MS SQLSERVER通用存储过程分页
查看>>
60.使用Azure AI 自定义视觉服务实现物品识别Demo
查看>>
Oracle 冷备份
查看>>
jq漂亮实用的select,select选中后,显示对应内容
查看>>