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()
 
 
 
												

python全栈开发 * 12 知识点汇总 * 180530的更多相关文章

  1. python全栈开发 * 01知识点汇总 * 180530

    一 python简介. 1.创始人:  吉多 .范罗苏姆  \   (Guido van Rossum). 2.时间  :  1989年. 3.主要应用领域  :  云计算 \  WEB开发  \   ...

  2. python全栈开发 * 14 知识点汇总 * 180530

    14 生成器表达式 内置函数# 一.迭代器 (补充)# 1.如何判断迭代对象,迭代器# (1).dir(obj)检测对象有没有iter方法,然后it=obj.__iter__() 获取迭代器 , it ...

  3. python全栈开发 * 10知识点汇总 * 180612

    10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...

  4. python全栈开发 * 32知识点汇总 * 180717

    32 网络编程 (一)一.架构 定义:程序员开发的一种模式. 分类: C/S 架构 C/S即:Client与Server , 客户端/ 服务器模式 . 缺点 : 冗余 B/S 架构 Browser与S ...

  5. python全栈开发 * 27知识点汇总 * 180710

    27   time  os  sys  模块 time 模块 一.表示时间的三种方式 时间戳(timestamp), 元组(struct_time),格式化时间字符串(Format string) 小 ...

  6. python全栈开发 * 26知识点汇总 * 180709

    26 logging collections random 模块 一.logging低配:日志不能写入文件与显示同时进行 import logging logging.basicConfig(leve ...

  7. python全栈开发 * 36知识点汇总 * 180721

    36 操作系统的发展史 进程一.手工操作--穿孔卡片 1.内容: 程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把程序和数据输入计算机内存,接着通过控制 台开关启动程序针对 ...

  8. python全栈开发 * 31知识点汇总 * 180716

    31 模块和包一.模块(一)模块的种类:内置模块,自定义模块,扩展模块第三方模块(二)自定义模块 1.模块的创建 : 新建一个py文件. 2.模块名 : 模块名需要符合变量的命名规范. 3.模块的导入 ...

  9. python全栈开发 * 24 知识点汇总 * 180705

    24 模块-------序列化一.什么是模块 模块:py文件就是一个模块.二.模块的分类:(1)内置模块 (登录模块,时间模块,sys模块,os模块)(2)扩展模块 (itchat 微信有关,爬虫,b ...

随机推荐

  1. Nginx配置,413 Request Entity Too Large错误解决

    今天有同事找我,说图片上传之后,不知道去哪里了.分析了一下问题,找到原因之后做了处理,这里简要记录一下. 问题原因: 1.首先后台log并无错误信息: 2.捡查了一下浏览器,发现network中有报错 ...

  2. JAVA中使用Log4j2日志和Lombok引入日志的方法

    一.简述 我们项目中既要使用lombok,又要使用log4j2时,使用日志将会更简单. 二.解决 1.引入依赖 <dependency> <groupId>org.apache ...

  3. simHash 简介以及 java 实现

    传统的 hash 算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法.产生的两个签名,如果相等,说明原始内容在一定概 率 下是相等的:如果不相等,除了说明原始内容不相等外 ...

  4. PHP会员找回密码功能实现实例介绍

    设置思路 1.用户注册时需要提供一个E-MAIL邮箱,目的就是用该邮箱找回密码. 2.当用户忘记密码或用户名时,点击登录页面的“找回密码”超链接,打开表单,并输入注册用的E-MAIL邮箱,提交. 3. ...

  5. C++ thread类多线程编程

    https://blog.csdn.net/dcrmg/article/details/53912941 多线程操作的thread类,简单多线程示例: #include <iostream> ...

  6. Django Http请求生命周期

    day54 请求响应Http 1.发送Http请求 2.服务器接收,根据请求头中的的url在路由关系表中进行匹配(从上到下) 3.匹配成功后,执行指定的views函数 4.业务处理 URL----&g ...

  7. WCF-Oracel适配器针对UDT的使用配置与注意事项

    配置方法 1.针对Oracle UDT 的数据类型需要在开发过程中手动配置生成的DLL位置和Key位置,Visual Studio->添加生成项目->Add Adapter Metadat ...

  8. ero-configuration Web Application Debugging with Xdebug and PhpStorm

    1. Install Xdebug To use Xdebug with PhpStorm for debugging PHP applications, you need to have a PHP ...

  9. HMACSHA1 加密算法

    https://blog.csdn.net/z69183787/article/details/78393216 ******************************************* ...

  10. Docker入门简记

    Docker的容器环境实际上是借助类Linux命名空间,将各种系统资源按照容器不同划分了不同的命名空间进行隔离,为各个进程提供独立的运行环境关键概念:容器,镜像两个概念一起看,镜像好比平常系统中的各个 ...