zoukankan      html  css  js  c++  java
  • Python-详解装饰器及反射原理

    一、装饰器

    装饰器:装饰函数和类,作用:扩展增加函数和类的功能

    二、装饰器的分类

    两大类:装饰器函数和装饰器类

    三、装饰器函数定义及应用

    函数: 封装代码最小单元,提供代码复用性

    • 装饰器函数利用函数的一些特征:
      1. 函数可以用为参数;

      2. 函数可以作为变量;

      3. 函数也可以返回函数;

    • 装饰器函数可以装饰所有的函数(有参数,没参数)
    import time
    
    
    def runTime(func):
        """
        装饰函数
        原来功能 + 扩展的功能: 统计每个函数的耗时
        :param func:
        :return:
        """
        def wrapper(*args,**kwargs):
            start = time.time()
            #原来功能
            func(*args, **kwargs)
            end = time.time()
            cost = end - start
            print(f"统计函数使用时长:{func.__name__}耗时{cost}s")
        return wrapper
    
      
    @runTime
    def test_no_params():
        print("这是一个无参数的装饰器测试")
        
        
    
    @runTime
    def test_have_params(*args,**kwargs):
        sum = 0
        for num in args:
            sum += num
        print(f"求和: {sum}")
        return sum
    
      
    test_no_params()
    test_have_params(2,4,3,5,6,8,9)

    四、装饰器类

    装饰器类的实质:

    调用装饰类中的__call__内置函数

    import time
    
    
    #定义装饰器类  ------>本质类 作用: 原来功能 + 扩展功能
    class Dec:
        #原来功能 self._func()
        def __init__(self,func):
            self._func = func
        
        #扩展功能
        def __call__(self, *args, **kwargs):
            """
            __call__函数: 实例化对象()
            :param args: 
            :param kwargs: 
            :return: 
            """
            start = time.time()
            #原来功能
            self._func()
            end = time.time()
            cost = end - start
            print(f"该函数{self._func.__name__}耗时: {cost}s")
            return cost
    
    @Dec
    def test_no_param():
        """被装饰器函数"""
        print("测试函数无参数")
        time.sleep(2)
    
    @Dec
    def test_have_param(*args,**kwargs):
        """被装饰器函数"""
        sum = 0
        for i in args:
            sum += i
        print(f"sum函数耗时: {sum}s")
        time.sleep(1)
    
    print(test_no_param())
    print(test_have_param([1,4,6,3,7,9]))

    五、装饰器应用场景

    常见的场景:授权及日志的收集、认证等

    """
     1、编写装饰器,为多个函数加上认证的功能,要求登录成功一次,后续的函数都无需再输入用户名和密码
    """
    
    FALG = False
    def login(user,passwd):
        with open(file='admin',mode='r',encoding='utf-8') as f:
            if f.readline().strip() == user and f.readline().strip() == passwd:
                return True
            return False
    
    def certification(func):
        def wrapper(*args, **kwargs):
            global FALG
            if FALG:
               res = func(*args, **kwargs)
            else:
                user = input("请输入用户名:")
                password = input("请输入密码: ")
                if login(user,password):
                    print("登录成功")
                    res = func(*args, **kwargs)
                    FALG = True
                else:
                    print("登录失败")
                    return
            return res
        return wrapper
    
    @certification
    def shop_add():
        print("增加一个商品")
    
    @certification
    def shop_del():
        print("删除一个商品")
    
    shop_add()
    shop_del()
    
    
    
    """
    2.编写装饰器,为多个函数加上记录调用功能,要求每次调用都将被调用的函数名写入文件
    """
    
    def log(func):
        def wrapper(*args, **kwargs):
            with open(file="admin", mode="a", encoding="UTF-8") as file:
                file.write(func.__name__ + '
    ')
            res = func(*args, **kwargs)
            return res
        return wrapper
    
    @log
    def shop_1():
        print("这是商店1")
    
    @log
    def shop_2():
        print("这是商店2")
    
    
    shop_1()
    shop_2()
    
    
    

    六、反射

    把字符串映射到实例的变量或者实例的方法,然后可以进行调用、修改操作

    反射四个重要的方法:

    1. getattr   获取运动象属性/方法

    2. hasattr  判断对象是否有对应的属性

    3. delattr  删除指定属性

    4. setattr 为对象设置内容

    三十六般武艺,七十二般变化,修练出个人品牌并发出光芒
  • 相关阅读:
    Spring MVC Ajax 嵌套表单数据的提交
    Spring MVC 过滤静态资源访问
    Spring MVC 页面跳转时传递参数
    IDEA Maven 三层架构 2、运行 springMVC
    IDEA Maven 三层架构 1、基本的Archetype 搭建
    EasyUI DataGrid 基于 Ajax 自定义取值(loadData)
    Spring MVC Ajax 复杂参数的批量传递
    Mybatis Sql片段的应用
    在 Tomcat 8 部署多端口项目
    自动升级的设计思路与实现
  • 原文地址:https://www.cnblogs.com/deeptester-vv/p/15137104.html
Copyright © 2011-2022 走看看