zoukankan      html  css  js  c++  java
  • Day 11:函数装饰器

    在说装饰器前,先说一个东西,再Python里,有一个 一切皆对象,一切皆变量。

    例:

     1 def hello(name="sunjinyao"):
     2     return "hi " + name
     3 print(hello())
     4 # 输出: 'hi sunjinyao'
     5 # 我们可以将一个函数赋值给一个变量,比如
     6 hi = hello
     7 # 我们这里没有在使用小括号,因为我们并不是在调用hello函数
     8 # 而是在将它放在greet变量里头。我们尝试运行下这个
     9 print(hi())
    10 # 输出: 'hi sunjinyao'

    装饰器:就是给其他函数添加新功能。本质也是个函数。

    原则:1.不修改被装饰器函数的源代码2.不修改被装饰函数的调用方式

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

    高阶函数:函数接收的参数是个函数名或者函数的返回是一个函数名

    函数嵌套:定义的函数内还有函数,一层套一层

    闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

    装饰器框架:

    1 #例,变量名随需求更改,这里只是例子
    2 def login(func):#参数func代表要装饰的函数
    3     def inner(*args,**kwargs):#装饰器的参数不固定
    4         #在这里添加需要的功能
    5         ret = func(*args,**kwargs)
    6         #再这里添加需要的功能
    7         return ret
    8     return inner #没有()没有执行

     例:为TEST函数写一个装饰器,统计TEST函数的运行时间

     1 #为TEST函数写一个装饰器,统计TEST函数的运行时间
     2 import time #导入时间模块
     3 def time_1(func):#func = my_test
     4     def inner():
     5         start_time = time.time()
     6         ret = func()
     7         stop_time = time.time()
     8         print('函数的运行时间为%s'%(stop_time-start_time))
     9         return ret
    10     return  inner
    11 @time_1 #必须在所装饰的函数前使用。
    12 #@time_1 == my_test = time_1(my_test)
    13 def my_test():
    14     time.sleep(3)
    15     print('test函数运行完毕')
    16   return '这个是my_test的执行结果'
    17 #my_test = time_1(my_test) 18 #time_1(my_test) 相当inner函数内存地址 因为time1的reture结果是inner 19 print(my_test())#执行了inner函数

    练一练:#编写装饰器,为多个函数加上认证功能(用户密码来源于文件),要求登录一次,后续函数无需再输入密码。输入的密码为3次。

    例:文件内容

    abc,123
    def,456
     1 login_status = False
     2 def login(func):
     3     def inner(*args,**kwargs):
     4         global login_status
     5         if not login_status:
     6             count = 0
     7             while count < 3:
     8                 user_name =input('请输入用户名:')
     9                 pass_word =input('请输入密码:')
    10                 with open('my_file',encoding='utf8') as passwd_file:
    11                     for line in passwd_file:
    12                         login_name,login_pwd = line.strip().split(',')
    13                         #用,号分割账号密码并赋值,文件末尾都是有换行的,去掉空格(strip在前)
    14                         if user_name == login_name and pass_word == login_pwd:
    15                             login_status = True
    16                             print('登录成功')
    17                             count += 3 #为了跳出while循环
    18                             ret = func(*args, **kwargs)
    19                             return ret#跳出了for循环
    20                         else:
    21                             print('登录失败,请重新登录')
    22                             count += 1
    23                             break
    24         elif login_status:#在上面循环中,把Login_status状态改成 True之后,就不需要再次输入密码
    25             ret = func(*args, **kwargs)
    26             return ret
    27     return  inner
    28 @login
    29 def shopping_web():
    30     return '购物界面'
    31 @login
    32 def home_web():
    33     return '个人中心'
    34 shopping_web()
    35 home_web()
    36 print(home_web())
    37 print(shopping_web())
    38 print(home_web())
    人生苦短,我用Python
  • 相关阅读:
    System.Web.Mvc.HttpHeadAttribute.cs
    System.Web.Mvc.HttpOptionsAttribute.cs
    System.Web.Mvc.HttpDeleteAttribute.cs
    sqlite-dbeaver-heidisql
    java实现圆周率
    java实现圆周率
    java实现圆周率
    java实现圆周率
    java实现圆周率
    java实现最近距离
  • 原文地址:https://www.cnblogs.com/sunjinchao/p/10896893.html
Copyright © 2011-2022 走看看