python@装饰符

'''
# 不改变原函数代码,在调用原函数之前或之后执行其他代码

# 不加参数是两层def,会直接将原函数地址传递进来,返回new_fun(带原函数地址)下的inner函数
# 原函数执行前调用的函数(统一参数)
# def new_fun(sfunc):
#     def inner(args):
#         # 新添加内容
#         print('装饰符...')
#         sfunc(args)
#     return inner


# 原函数执行前调用的函数(不统一参数)
# def new_fun(sfunc):
#     # 如果多个函数使用这个装饰符,而函数,参数不一致的情况下,可以使用 *和**
#     def inner(*args, **kwargs):
#         # 新添加内容
#         print('装饰符...')
#         sfunc(*args, **kwargs)
#     return inner


# 原函数执行前调用的函数(不统一参数,且带返回值)
def new_fun(sfunc):
    # 如果多个函数使用这个装饰符,而函数,参数不一致的情况下,可以使用 *和**
    def inner(*args, **kwargs):
        # 新添加内容
        print('装饰符...')
        # 如果函数是带返回值的,就要加return返回
        return sfunc(*args, **kwargs)
    return inner


@new_fun
def print_str(tstr):
    print('str传递进来 %s ' % tstr)
    return tstr


def print_int(tint, tint2):
    print('int传递进来 %d %d' % (tint, tint2))
    return tint, tint2

print_int = new_fun(print_int)
# 装饰符相当于这样上面这句代码:
# 将原函数地址传递进new_fun,返回的是new_fun里的inner函数的地址,那么原函数地址调用时就是inner地址,相当于执行inner函数
# inner的形参和原函数形参相同,那么将参数传递进inner,就可以将参数传递进原函数,然后执行原函数
# 如果new_fun里不嵌套inner,那么在加载代码的时候就会直接执行new_fun内代码,达不到调用原函数时才执行的效果



rs = print_str('测试str')
rt1, rt2 = print_int(10086, 5566)
print(rs, rt1, rt2)'''


# 执行原函数前先执行的功能,在装饰器之前定义,不然无法找到地址
def before_func():
    print('before')


# 执行原函数后再执行的功能
def after_func():
    print('after')


# 多参装饰器(三层def),第一层装载装饰器参数,第二层装载原函数地址,第三层装载调用时的实际参数
def func_frame(before, after):
    def main_func(sourse_func):
        def inner(*args, **kwargs):
            before()
            sourse_func(*args, **kwargs)
            after()
        return inner
    return main_func


#@func_frame(before_func,after_func)
def print_tuple(tup=()):
    for i in tup:
        print(i)
    return 'True'

print_tuple = func_frame(before_func, after_func)(print_tuple)
# 多参装饰器相当于上面这句,等同于 @func_frame(before_func,after_func)
# 先执行func_frame()函数,将参数传递进函数体,返回函数体内装载有参数的main_func函数地址
# 接着执行返回的main_func()函数,将原函数地址传递进去,返回装载有装饰器参数和原函数地址的sourse_func函数地址
# 最后将sourse_func函数地址赋值给原函数,下次调用原函数名,
# 实际调用的是func_frame(带有参数值)下的main_func(带有原函数地址)下的sourse_func函数
# 那么在sourse_func里就可以操作func_frame的参数(可以是函数地址,也可以是其他数据类型)和调用原函数功能
# 如果装饰器是函数,那么就可以执行对应函数功能,不是的话,可以用装饰器参数执行判断等功能
# 以后在不改变原函数代码和装饰器代码的情况下,只需将写好功能的函数地址传递进装饰器就可以达到在执行原函数
# 之前和之后添加功能的效果


print_tuple((1, 2, 3, 4, 5, 6))

  

原文地址:https://www.cnblogs.com/xh4528/p/6538722.html