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 为对象设置内容

    三十六般武艺,七十二般变化,修练出个人品牌并发出光芒
  • 相关阅读:
    android 入门-ID
    Win10 VS2015 社区版切换到VS2013社区版 进行维护之前的项目
    Win10 AppBar
    Win10 保存Element到相册
    LRUCache c#
    Winform解决界面重绘闪烁的问题
    使用Emit实现给实体赋值
    Winform 自定义窗体皮肤组件
    WPF 分享一种背景动画效果
    使用MEF与Castle实现AOP
  • 原文地址:https://www.cnblogs.com/deeptester-vv/p/15137104.html
Copyright © 2011-2022 走看看