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

 

posted @ 2017-06-19 23:13  LiChaoAI  阅读(161)  评论(0编辑  收藏  举报