Python-详解装饰器及反射原理
一、装饰器
装饰器:装饰函数和类,作用:扩展增加函数和类的功能
二、装饰器的分类
两大类:装饰器函数和装饰器类
三、装饰器函数定义及应用
函数: 封装代码最小单元,提供代码复用性
- 装饰器函数利用函数的一些特征:
- 
- 
函数可以用为参数; 
- 
函数可以作为变量; 
- 
函数也可以返回函数; 
 
- 
- 装饰器函数可以装饰所有的函数(有参数,没参数)
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__ + '\n')
        res = func(*args, **kwargs)
        return res
    return wrapper
@log
def shop_1():
    print("这是商店1")
@log
def shop_2():
    print("这是商店2")
shop_1()
shop_2()
六、反射
把字符串映射到实例的变量或者实例的方法,然后可以进行调用、修改操作
反射四个重要的方法:
- 
getattr 获取运动象属性/方法 
- 
hasattr 判断对象是否有对应的属性 
- 
delattr 删除指定属性 
- 
setattr 为对象设置内容 
    三十六般武艺,七十二般变化,修练出个人品牌并发出光芒
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号