• Day 19 函数之闭包、装饰器


    一、什么是装饰器

    器即函数
    装饰即修饰,意指为其他函数添加新功能
    装饰器定义:本质就是函数,功能是为其他函数添加新功能

    二、装饰器遵循的原则

    1.不修改被装饰函数的源代码(开放封闭原则)
    2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

    三、高阶函数

    高阶函数总结
    1.函数接收的参数是一个函数名
      作用:在不修改函数源代码的前提下,为函数添加新功能,
      不足:会改变函数的调用方式
    2.函数的返回值是一个函数名
      作用:不修改函数的调用方式
      不足:不能添加新功能

    其、程序:

    work:

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "DaChao"
    # Date: 2017/6/14
    
    import time
    import random
    
    #一:编写函数,(函数执行的时间是随机的)
    
    # def work1_ti_work():
    #     '''
    #     函数执行的时间是随机的
    #     :return:
    #     '''
    #     time.sleep(random.randrange(1,6))
    #     print("Welcome to my world!")
    
    #二:编写装饰器,为函数加上统计时间的功能
    
    # def count_time(func):
    #     '''
    #     装饰器功能,增加计算运行时间功能!
    #     :param func:
    #     :return:
    #     '''
    #     def wrapper():
    #         start_time = time.time()
    #         func()
    #         end_time = time.time()
    #         print("Run time is %s" %(end_time-start_time))
    #     return wrapper
    #
    # @count_time
    # def work2_ti_work():
    #     '''
    #     函数执行时间是随机的。
    #     :return:
    #     '''
    #     time.sleep(random.randrange(3,6))
    #     print("Welcome to my world!")
    #
    # work2_ti_work()
    
    #三:编写装饰器,为函数加上认证的功能
    
    # def check(func):
    #     '''
    #     修饰器:增加认证功能!
    #     :return:
    #     '''
    #     def wrapper(*args,**kwargs):
    #         usrname = input("Please input your name: ").strip()
    #         echo = input("Please input your echo: ").strip()
    #         if usrname == "dachao"  and echo == "123":
    #             print("Login successful!")
    #             func(*args,**kwargs)
    #         else:
    #             print("Login error!")
    #     return wrapper
    #
    # @check
    # def work3_ti_work(usr):
    #     '''
    #     函数执行时间是随机的。
    #     :return:
    #     '''
    #     time.sleep(random.randrange(3,6))
    #     print("%s,welcome to my world!" %(usr))
    #
    # work3_ti_work("dachao")
    
    # 附:双修饰器增加功能:用户验证和登录时间统计
    
    # def count_time(func):
    #     '''
    #     装饰器功能,增加计算运行时间功能!
    #     :param func:
    #     :return:
    #     '''
    #     def wrapper(*args,**kwargs):
    #         start_time = time.time()
    #         func(*args,**kwargs)
    #         end_time = time.time()
    #         print("Run time is %s" %(end_time-start_time))
    #     return wrapper
    #
    # def check(func):
    #     '''
    #     修饰器:增加认证功能!
    #     :return:
    #     '''
    #     def wrapper(*args,**kwargs):
    #         usrname = input("Please input your name: ").strip()
    #         echo = input("Please input your echo: ").strip()
    #         if usrname == "dachao"  and echo == "123":
    #             print("Login successful!")
    #             func(*args,**kwargs)
    #         else:
    #             print("Login error!")
    #     return wrapper
    #
    # @count_time      #work3_ti_work = count_time(check(work3))
    # @check           #work3_ti_work = check(work3)
    # def work3_ti_work(usr):
    #     '''
    #     函数执行时间是随机的。
    #     :return:
    #     '''
    #     time.sleep(random.randrange(3,6))
    #     print("%s,welcome to my world!" %(usr))
    #
    # work3_ti_work("dachao")
    
    #四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
    # 要求登录成功一次,后续的函数都无需再输入用户名和密码
    #    注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
    
    # a = eval('{"name":"egon","password":"123"}')
    #
    # tag = True
    #
    # def count(func):
    #     def wrapper():
    #         global tag
    #         while tag:
    #             username = input("Please input your name: ").strip()
    #             echo = input("Please input your echo: ").strip()
    #             if username == a["name"] and echo == a["password"]:
    #                 tag = False
    #                 func()
    #             else:
    #                 print("Please input again!")
    #         func()
    #     return wrapper
    #
    # @count
    # def work_1():
    #     print("111111111111111")
    # @count
    # def work_2():
    #     print("222222222222222")
    # @count
    # def work_3():
    #     print("333333333333333")
    #
    # work_1()
    # work_2()
    # work_3()
    
    #五:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
    
    # from urllib.request import urlopen
    #
    # def get_url(url):
    #     '''
    #     从用户传入的地址,返回内容
    #     :return:
    #     '''
    #     res = urlopen(url).read()
    #     return res
    
    #六:为题目五编写装饰器,实现缓存网页内容的功能:
        # 具体:实现下载的页面存放于文件中,
    #       如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,
        # 否则,就去下载,然后存到文件中
    
    from urllib.request import urlopen
    
    def url_cache(func):
        def wrapper(*args,**kwargs):
            print("11111")                  #测试
            f = open("cache1.txt","r")
            if(f.read() == ""):
                print("2222")               #测试
                f.close()                   #一定记得要关闭文件
                f = open("cache1.txt", "wb")
                f.write(func(*args,**kwargs))
                f.close()
            else:
                print("3333")               #测试
        return wrapper
    
    @url_cache
    def get_url(url):
        '''
        从用户传入的地址,返回内容
        :return:
        '''
        res = urlopen(url).read()
        return res
    
    get_url('http://www.baidu.com')
    
    #七:还记得我们用函数对象的概念,制作一个函数字典的操作吗,
    # 来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
    
    # import sys
    #
    # func_dic = dict({})
    #
    # def deco(func):
    #     def inner():
    #         func_dic[func.__name__] = getattr(sys.modules[__name__],func.__name__)
    #         func()
    #     return inner
    # @deco
    # def my_append():
    #     print("My_appeng is running!")
    # @deco
    # def my_sss():
    #     print("My_sss is running!")
    #
    # my_append()
    # my_sss()
    # print(func_dic)
    # func_dic["my_append"]()
    work
  • 相关阅读:
    在Ubuntu下安装TensorFlow-gpu版本
    ubuntu安装和卸载软件命令
    Window7通过Anaconda安装Tensorflow
    Kaggle Titanic Data Science Solutions
    CNN、RNN和DNN的区别
    卷积神经网络介绍
    大数据随想
    golang omitempty 总结
    LeetCode 856 递归思路详解
    安装Nginx的各种报错的解决
  • 原文地址:https://www.cnblogs.com/LiChaoAI/p/7015828.html
Copyright © 2020-2023  润新知