zoukankan      html  css  js  c++  java
  • 函数 (三) 装饰器

    一 为何要用装饰器

    有的时候写完一段代码,过段时间需要对它进行升级、添加一些新功能,但是如果要直接修改原来的代码会影响其他人的调用,所以就需要一个不修改源代码且不修改原函数的调用方式的东西又能为原函数增添新功能的东西,装饰器就是干这个的。

    二 什么是装饰器

    装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
    强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
    装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
    开放封闭原则:对修改封闭,对扩展开放

    三 装饰器的使用

    下面是为一个函数添加装饰器,添加了计算其运行时间的功能:

     1 import time
     2 def timmer(func):
     3     def wrapper(*args,**kwargs):
     4         start_time=time.time()
     5         res=func(*args,**kwargs)
     6         stop_time=time.time()
     7         print('run time is %s' %(stop_time-start_time))
     8         return res
     9     return wrapper
    10 
    11 @timmer
    12 def foo():
    13     time.sleep(3)
    14     print('from foo')
    15 foo()
    

    四、装饰器语法及固定格式

    1 def 装饰器函数名(func):
    2     def wrapper(*args,**kwargs):    
    3         ret = func(*args,**kwargs)
    4         return ret
    5     return wrapper
    6 
    7 @装饰器函数名
    8 def func():
    9    pass

    五、应用练习

     1 #######################################作业练习#######################################################
     2 #
     3 # 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
     4 # user_exist = [False]
     5 # def auth(func):
     6 #     def wrapper(*args,**kwargs):
     7 #         #注册功能
     8 #         with open('db.txt','r',encoding='utf-8') as f:
     9 #             user_dic = eval(f.read())
    10 #             flag = False
    11 #         while not user_exist[0]:
    12 #             username = input('请输入您的用户名:').strip()
    13 #             password = input('请输入您的密码:').strip()
    14 #             if username in user_dic and password == user_dic[username]:
    15 #                 print('恭喜您,登录成功!')
    16 #                 user_exist[0] = True
    17 #                 break
    18 #             else:
    19 #                 print('账号或密码错误,请重新输入!')
    20 #         ret = func(*args,**kwargs)
    21 #         return ret
    22 #     return wrapper
    23 #
    24 # @auth
    25 # def func1():
    26 #     print('函数1')
    27 # @auth
    28 # def func2(x):
    29 #     print('函数2',x)
    30 # func1()
    31 # func2(111111)
    32 # 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
    33 # def log(func):
    34 #     def wrapper(*args,**kwargs):
    35 #         with open('db2.txt','a',encoding='utf-8') as f:
    36 #             f.write('%s函数正在被调用。
    '%func.__name__)
    37 #         ret = func(*args,**kwargs)
    38 #         return ret
    39 #     return wrapper
    40 # @log
    41 # def func1():
    42 #     print('func1函数被调用了。。。。')
    43 # @log
    44 # def func2():
    45 #     print('func2函数被调用了。。。。')
    46 #
    47 # func1()
    48 # func2()
    49 # 进阶作业(选做):
    50 # 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
    51 from urllib.request import urlopen
    52 
    53 # def get_html(url):
    54 #     print(urlopen(url).read())
    55 #
    56 # get_html('http://www.baidu.com')
    57 # 2.为题目1编写装饰器,实现缓存网页内容的功能:
    58 # 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
    59 # from urllib.request import urlopen
    60 # 
    61 # def get_bak(func):
    62 #     def wrapper(*args,**kwargs):
    63 #         with open('html.bak','r+',encoding='utf-8') as f:
    64 #             if not f.read():
    65 #                 ret = func(*args, **kwargs)
    66 #                 print(ret)
    67 #                 f.write(ret.decode('utf-8'))
    68 #             else:
    69 #                 print('以下内容是从缓存中获得的^^^^^')
    70 #                 f.seek(0)
    71 #                 print(f.read())
    72 #         ret = func(*args, **kwargs)
    73 #         return ret
    74 #     return wrapper
    75 # 
    76 # @get_bak
    77 # def get_html(url):
    78 #     return urlopen(url).read()
    79 # get_html('http://www.python.org')
  • 相关阅读:
    Git使用(真的有熟悉吗)
    webpack中webpack.config.js的相关配置表
    import和require(你有过疑惑么)
    webpack打包(离开脚手架,你还好吗)
    webpack再度学习
    最大子段和之分治法
    快速排序之随机快排
    棋盘覆盖问题(看完这个就好)
    稳定匹配问题(脱单就靠这波了)
    Jieba统计词频并生成csv文件
  • 原文地址:https://www.cnblogs.com/fu-yong/p/8135683.html
Copyright © 2011-2022 走看看