zoukankan      html  css  js  c++  java
  • Python学习(十)—— 装饰器和函数闭包

    装饰器

    装饰器:本质就是函数,功能是为其他函数添加附加功能

    原则:

    1、不修改被修饰函数的源代码

    2、不修改被修饰函数的调用方式

    统计程序运行的时间(不使用装饰器):

      这种方法修改了源代码,不能用于已经上线的程序

     1 import time
     2 def calc(l):
     3     res = 0
     4     start_time = time.time()
     5     for i in l:
     6         res += i
     7         time.sleep(0.01)
     8     stop_time = time.time()
     9     print(stop_time - start_time)
    10     return res
    11 
    12 y = calc([1,2,3,4,5,6,7,8,9,10])
    13 print(y)
    14 # 0.1087961196899414
    15 # 55

      这种方法修改了调用方式

     1 import time
     2 def timmer(func):
     3     start_time = time.time()
     4     y = func()
     5     stop_time = time.time()
     6     print(stop_time - start_time,"
    ",y)
     7     return timmer
     8 
     9 def calc():
    10     res = 0
    11     for i in range(1,11):
    12         res += i
    13         time.sleep(0.01)
    14     return res
    15 
    16 timmer(calc)
    17 
    18 # 0.10875916481018066 
    19 #  55

    统计程序运行的时间(使用装饰器):

     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(stop_time - start_time)
     8         return res
     9     return wrapper
    10 @timmer
    11 def calc(l):
    12     res = 0
    13     for i in l:
    14         res += i
    15         time.sleep(0.01)
    16     return res
    17 
    18 y = calc([1,2,3,4,5,6,7,8,9,10])
    19 print(y)
    20 # 0.10654282569885254
    21 # 55

    装饰器 = 高阶函数 + 函数嵌套 + 闭包

    高阶函数 

    高阶函数的定义:满足下列任一条即可

    1、函数接收的参数是一个函数名

    2、函数的返回值是一个函数名

    函数嵌套 

    在函数内部嵌套另一个函数

    闭包

    装饰器的框架

     1 import time
     2 def timmer(func): #参数是函数
     3     def wrapper(): #函数的嵌套
     4         start_time= time.time()
     5         # print(func)
     6         func() #函数闭包所以可以调用func
     7         end_time = time.time()
     8         print("running time is %s"%( end_time-start_time))
     9     return wrapper #返回是函数
    10 @timmer  #装饰器名,相当于test = timmer(test),置于被修饰函数之前
    11 def test():
    12     time.sleep(3)
    13 
    14 test()
    15 # running time is 3.000131368637085

    有参数的情况下框架:

     1 import time
     2 def timmer(func): #参数是函数
     3     def wrapper(*args,**kwargs): #函数的嵌套
     4         s_time = time.time()
     5         func(*args,**kwargs) #函数闭包所以可以调用func
     6         e_time = time.time()
     7         print("running time :" ,e_time-s_time)
     8     return wrapper #返回是函数
     9 @timmer
    10 def test(name,gender,age):
    11     time.sleep(3)
    12     print(name)
    13     print(gender)
    14     print(age)
    15 
    16 test("ally","female",20)
    17 # ally
    18 # female
    19 # 20
    20 # running time : 3.000988245010376

    例子

      给主页加登录装饰器(出现重复登录情况)

     1 #!/usr/bin/env python 
     2 # -*- coding:utf-8 -*-
     3 def login(func):
     4     def wragger(*args, **kwargs):
     5         x = input("请输入用户名:")
     6         y = int(input("请输入密码:"))
     7         if x == "admin" and y == 123456:
     8             print("登录成功")
     9             res = func(*args, **kwargs)
    10             return res
    11         else:
    12             pass
    13 
    14     return wragger
    15 
    16 
    17 @login
    18 def index():
    19     print("欢迎来到京东")
    20 
    21 
    22 @login
    23 def home():
    24     print("欢迎回家")
    25 
    26 
    27 @login
    28 def shopping_car():
    29     print("我的购物车")
    30 
    31 
    32 @login
    33 def order():
    34     print("我的订单")
    35 
    36 
    37 index()
    38 # 请输入用户名:admin
    39 # 请输入密码:123456
    40 # 登录成功
    41 # 欢迎来到京东
    View Code

      给主页加登录装饰器的例子(不需重复登录)

     1 user_dic ={"user_name":None,"login":False}
     2 def auth_login(func):
     3     def wragger(*args, **kwargs):
     4         if user_dic["user_name"] and user_dic["login"]:
     5             res = func(*args, **kwargs)
     6             return res
     7         else:
     8             user_name = input("请输入用户名:")
     9             password = int(input("请输入密码:"))
    10             if user_name == "admin" and password == 123456:
    11                 user_dic["user_name"] = user_name
    12                 user_dic["login"] = True
    13                 print("登录成功")
    14                 res = func(*args, **kwargs)
    15                 return res
    16     return wragger
    17 
    18 
    19 @auth_login
    20 def index():
    21     print("欢迎来到京东")
    22 
    23 
    24 @auth_login
    25 def home():
    26     print("欢迎回家")
    27 
    28 
    29 @auth_login
    30 def shopping_car():
    31     print("我的购物车")
    32 
    33 
    34 @auth_login
    35 def order():
    36     print("我的订单")
    37 
    38 index()
    39 shopping_car()
    40 order()
    41 
    42 # 请输入用户名:admin
    43 # 请输入密码:123456
    44 # 登录成功
    45 # 欢迎来到京东
    46 # 我的购物车
    47 # 我的订单
    View Code

      公司有多个用户

     1 #!/usr/bin/env python 
     2 # -*- coding:utf-8 -*-
     3 user_list = [
     4     {"user_name": "alex", "password": "123"},
     5     {"user_name": "admin", "password": "123456"},
     6 ]
     7 user_login = {"user_name": None, "login": False}
     8 
     9 def auth_login(func):
    10     def wragger(*args, **kwargs):
    11         if user_login["user_name"] and user_login["login"]:
    12             res = func(*args, **kwargs)
    13             return res
    14         else:
    15             user_name = input("请输入用户名:").strip()
    16             password = input("请输入密码:").strip()
    17             for user_dic in user_list:
    18                 if user_name == user_dic["user_name"] and password == user_dic["password"]:
    19                     user_login["user_name"] = user_name
    20                     user_login["login"] = True
    21                     print("登录成功")
    22                     res = func(*args, **kwargs)
    23                     return res
    24             else:
    25                 print("用户或密码错误")
    26     return wragger
    27 
    28 @auth_login
    29 def index():
    30     print("欢迎来到京东")
    31 
    32 @auth_login
    33 def home():
    34     print("欢迎回家")
    35 
    36 @auth_login
    37 def shopping_car():
    38     print("我的购物车")
    39 
    40 @auth_login
    41 def order():
    42     print("我的订单")
    43 
    44 index()
    45 shopping_car()
    46 order()
    47 
    48 # 请输入用户名:admin
    49 # 请输入密码:123456
    50 # 登录成功
    51 # 欢迎来到京东
    52 # 我的购物车
    53 # 我的订单

    函数闭包带参数装饰器

     1 #!/usr/bin/env python 
     2 # -*- coding:utf-8 -*-
     3 user_list = [
     4     {"user_name": "alex", "password": "123"},
     5     {"user_name": "admin", "password": "123456"},
     6 ]
     7 user_login = {"user_name": None, "login": False}
     8 
     9 def auth(auth_type="filedb"):
    10     def auth_login(func):
    11         def wragger(*args, **kwargs):
    12             if auth_type == "filedb":
    13                 if user_login["user_name"] and user_login["login"]:
    14                     res = func(*args, **kwargs)
    15                     return res
    16                 else:
    17                     user_name = input("请输入用户名:").strip()
    18                     password = input("请输入密码:").strip()
    19                     for user_dic in user_list:
    20                         if user_name == user_dic["user_name"] and password == user_dic["password"]:
    21                             user_login["user_name"] = user_name
    22                             user_login["login"] = True
    23                             print("登录成功")
    24                             res = func(*args, **kwargs)
    25                             return res
    26                     else:
    27                         print("用户或密码错误")
    28             elif auth_type == "ldap":
    29                 print("lalal")
    30             else:
    31                 print("biubiubiu")
    32 
    33         return wragger
    34 
    35     return auth_login
    36 
    37 
    38 @auth(auth_type="filedb")  # auth_login=auth(auth_type="filedb" )--> @auth_login附加了auth_type形参-->index=auth_login(index)
    39 def index():
    40     print("欢迎来到京东")
    41 
    42 
    43 @auth(auth_type="ldap")
    44 def home():
    45     print("欢迎回家")
    46 
    47 
    48 @auth(auth_type="qqqq")
    49 def shopping_car():
    50     print("我的购物车")
    51 
    52 
    53 def order():
    54     print("我的订单")
    55 
    56 
    57 index()
    58 home()
    59 shopping_car()
    60 
    61 # 请输入用户名:alex
    62 # 请输入密码:123
    63 # 登录成功
    64 # 欢迎来到京东
    65 # lalal
    66 # biubiubiu
    View Code

    解压序列 

    交换值

    1 f1 = 1
    2 f2 = 2
    3 f1,f2 = f2,f1
    4 print(f1,f2)
    5 # 2 1

    一条语句多变量赋值,必须一一对应

     1 a,b,c = "hel"
     2 print("a:",a,"
    b:",b,"
    c:",c)
     3 # a: h
     4 # b: e
     5 # c: l
     6 x,y,z = 1,3,5
     7 print("x:",x,"
    y:",y,"
    z:",z)
     8 # x: 1
     9 # y: 3
    10 # z: 5
    11 u,v = [1,2],[4,5]
    12 print(u,v)
    13 # [1, 2] [4, 5]

    如果只想取出特定值,可以不用索引

    1 l = [0,1,2,3,4,5,6,7,8,9]
    2 a,*_,b = l #实际上,可以使用*+任何字母或符号
    3 print(a)
    4 print(b)
    5 # 0
    6 # 9
  • 相关阅读:
    ASP.NET Core2利用MassTransit集成RabbitMQ
    ASP.NET Core2集成Office Online Server(OWAS)实现办公文档的在线预览与编辑(支持wordexcelpptpdf等格式)
    ASP.NET Core2利用Jwt技术在服务端实现对客户端的身份认证
    net core System.Drawing is not supported on this platform.
    小程序开发之维护access_token
    net core 100个案例
    msgSystem.Drawing is not supported on this platform【netcore】
    wpf,前端动画demo,鱼眼效果
    自定义控件,重写 TextBox 实例
    TextBox输入法控制,进入输入框则启用或禁用输入法(ime),禁用后只能输入英文
  • 原文地址:https://www.cnblogs.com/jennifer224/p/12399008.html
Copyright © 2011-2022 走看看