python----装饰器

                                                                                          装饰器

一:楔子

          假如有一个函数,实现返回两个数的较大值:

      

ef my_max(x,y):
    m = x if x>y else y
    return m
bigger = my_max(10,20)
print(bigger)

20

二:装饰器的形成

              装饰器的本质:一个闭包函数(自由变量就是装饰的函数名)。

             装饰器的功能:在不修改原函数及其调用的方式的情况下对原函数功能进行扩展。

             装饰器的格式:

def timer(func):
    def inner(*args,**wkargs):
        #--执行函数之前要做的---
        re = func(*args,**wkargs)
        #--执行函数之后要做的--
        return re
    return inner

三:语法糖      

mport time                             #1
def timer(func2):                       #2
    def inner(*args,**kwargs):          #4
        start=time.time()                #5
        re =func2(*args,**kwargs)        #7
        print(time.time()-start)         #8
        return re                        #11
    return inner                         #12
@timer              #--func2=timer(func2) #3
def func2(a):
    print('in func2 and get a:%s'%(a))    #9
    return 'func2 over'                   #10
func2()                                       #6

四:开放闭封原则。

         1:对扩展开放

                    允许代码扩展,添加新功能。

         2:对修改封闭

                      我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

                     装饰器完美遵循开放闭封原则。

五:带参数的装饰器。

            

# def outer(flag):
#     def timer(func):
#         def inner(*args,**kwargs):
#             if flag:
#                 print('''执行函数之前要做的''')
#             re = func(*args,**kwargs)
#             if flag:
#                 print('''执行函数之后要做的''')
#             return re
#         return inner
#     return timer
# 
# @outer(False)
# def func():
#     print(111)
# func('')

六;多个装饰器装饰同一函数。

     

ef wrapp1(func):
    def inner():
        print('----------')
        func()
    return inner
def wrapp2(func):
    def inner():
        print('-------')
        func()
    return inner()

def func():
    print('------')
func()

       作业:

编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
要求登录成功一次,后续的函数都无需再输入用户名和密码
注意:从文件中读出字符串形式的字典,
可以用eval('{"name":"egon","password":"123"}')转成字典格式
'''
# user_dict = {
#     'pang':'123456',
#     'panda':'binbin',
#     'nezha':'101010'
# }

# print(type(user_dic))
auth_status = {
    'user':None,
    'status':False
}
def auth(func):
    def inner(*args,**kwargs):
        if auth_status['status']:
            ret = func(*args, **kwargs)  # index/home
            return ret
        else:
            username = input('username : ').strip()
            password = input('password : ').strip()
            # 读文件获取用户信息
            f = open('conf')
            user_info = f.read()
            user_dic = eval(user_info)
            if user_dic.get(username) and user_dic[username] == password:
                print('login successful')
                auth_status['user'] = username
                auth_status['status'] = True
                ret = func(*args,**kwargs)  #index/home
                return ret
            else:
                print('login failed')
    return inner

@auth
def index():
    print("欢迎来到首页")

@auth
def home():
    print("欢迎回家")

index()
index()
home()
index()

 

 

'''
进阶作业(选做):
1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
2.编写装饰器,实现缓存网页内容的功能:
具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),
就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
'''
url_l = []
from urllib.request import urlopen

def get_cache(func):
    def inner(*args,**kwargs):
        url = args[0]
        filename = str(hash(url))
        if url in url_l:
            f = open(filename,'rb')
            ret = f.read()
        else:
            url_l.append(url)
            ret = func(*args, **kwargs)
            f = open(filename,'wb')
            f.write(ret)
        f.close()
        return ret
    return inner

@get_cache
def get(url):
    return urlopen(url).read()

print(get('http://www.cnblogs.com/linhaifeng'))
print(get('http://www.cnblogs.com/linhaifeng'))
print(get('http://www.cnblogs.com/linhaifeng'))
print(get('http://www.cnblogs.com/linhaifeng'))
print(get('http://www.cnblogs.com/linhaifeng'))

 

posted @ 2017-07-28 15:55  H......T!  阅读(200)  评论(0编辑  收藏  举报