zoukankan      html  css  js  c++  java
  • python全栈开发 * 12 知识点汇总 * 180530

     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'xe6x8fx90' # 一个字符的utf-8 形式
    s=bys.decode("UTF-8") # 用UTF-8 解码成 字符串s
    gbk=s.encode("GBK") # 再把字符串转化成GBK (两个字节)
    print(gbk) # 结果 b'xccxe1'
    作业:

    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__+" "+time.strftime("%Y-%m-%d %H:%M:%S", struct_time)+" ") #文件名和和格式化后的时间添加到文件中

    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(" "+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)+' ')
    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()
     
     
     


  • 相关阅读:
    还原大备份mysql文件失败的解决方法
    第一次招聘
    Data Transformation Services (DTS) Package Example
    .net Page 执行事件顺序
    批量修改相同結構的table layout
    js 中exec、test、match、search、replace、split用法
    存储过程分页,按多条件排序(原创)
    Lisp 的本质 [转]
    【原创】jQuery方法的写法不同导致的兼容性
    WinForm 图片变灰方法
  • 原文地址:https://www.cnblogs.com/J-7-H-2-F-7/p/9187974.html
Copyright © 2011-2022 走看看