17.2-无参装饰器

作者: BeautifulSoulpy | 来源:发表于2019-09-18 21:15 被阅读0次

我饿了,你分给我一半面包,这是朋友。你只吃了一口,剩下的面包全给了我 ,这是爱情。你一口没吃,直接把面包给了我 ,这是父母。 所以请珍惜友情、爱情、亲情,没有谁对谁是应该的。要学会感恩知足!懂得珍惜,才会拥有!


Python 是一种对新手很友好的语言。但是,它也有很多较难掌握的高级功能,比如装饰器(decorator)
如果前面基础知识掌握比较牢固的话,装饰器迎刃而解,没有什么特别难的地方,只需要几个简单的转化、等价,很容易理解装饰器;

在 Python 中,函数是一种非常灵活的结构,我们可以把它赋值给变量、当作参数传递给另一个函数,或者当成某个函数的输出。装饰器本质上也是一种函数,它可以让其它函数在不经过修改的情况下增加一些功能。

Python之装饰器
本章总结:

  1. 硬编码:死死的写到函数中的,
  2. 函数传的参数是否符合上面函数定义的要求,那是在调用时候后的问题
  3. def logger(fn, *args, *kwargs): # 形参定义 与 ret = fn(args, **kwargs) # 参数解构 区别 ;参数-正不正确由核心代码判断;
  4. add = logger(add) add赋值重新定义,记录的是inner函数对象,inner传4,5;调用fn() 实质是记录原来的add(4,5)函数;fn用到了外部变量fn,相当于闭包的特性(记录add的引用,尽管add被重新定义);

装饰器(decorator)

动态附加功能的解决方案:
示例1:

业务核心的代码功能+\-
def add(x,y): #  z = f(x,y)
    return x+y
def sub(x,y):
    return x-y
def a(x,y,z):
    pass

def b(m,n,*args,x,y,**kwargs):
    pass

只关注 附加功能——print  的函数定义;记录函数参数,并不关注函数是否能运行;
def logger(fn,x,y):   #位置参数和关键字参数分开;
    print("call function {}. x={}, y={}".format(fn.__name__, x, y))
    ret = fn(x,y)
    return ret
def logger(fn, *args, **kwargs):    # 形参定义
    print("call function {}. x={}, y={}".format(fn.__name__, *args, **kwargs))
    ret = fn(*args, **kwargs)    #  参数解构
    return ret

print('result = {}'.format(logger(add,4,5)))  #add(4,5)
print('result = {}'.format(logger(b,4,5,6,7,x=10,y=13))) # b(4,5,6,7,x=10,y=13)

def add(x,y): #  z = f(x,y)
    return x+y

示例2:柯里化之后,变成了2层函数;
# def logger(fn,x,y):   #位置参数和关键字参数分开;
#     print("call function {}. x={}, y={}".format(fn.__name__, x, y))
#     ret = fn(x,y)
#    return ret

def logger(fn):
    def inner(*args,**kwargs):
        print("call function {}. x={}, y={}".format(fn.__name__, *args, **kwargs))
        ret = fn(*args, **kwargs)
        return ret
    return inner

logger(add,4,5)
logger(add)(4,5)
fn = logger(add)
ret = add(4, 5)
print(ret)

# add赋值重新定义,记录的是inner函数对象,inner传4,5;调用fn() 实质是记录原来的add(4,5)函数;fn用到了外部变量fn,相当于闭包的特性;(记录add的引用,尽管add被重新定义);

add = logger(add)   #inner 原来的add消失了吗?
ret = add(4,5)  
----------------------------------------
call function add. x=4, y=5
9


最终形态——装饰器:
def logger(fn):
    def inner(*args,**kwargs):
        print("call function {}. x={}, y={}".format(fn.__name__, *args, **kwargs))
        ret = fn(*args, **kwargs)    # 解构,闭包(内外层函数的变量;)
        return ret
    return inner

@logger    # 等价为  add = logger(add)  =》 add=inner
#@logger    # 注释后相当于一个附加功能消失;
def add(x,y): #  z = f(x,y)
    return x+y

ret = add(4, 5)     #   开始调用;ret=inner(4,5)    
print(ret)
--------------------------------------------------
call function add. x=4, y=5

装饰器总结:
1. @logger 新语法的能力:就是将下面的标识符add作为参数传进来;

logger 包装 add ;
def logger(fn):
    def wrapper(*args,**kwargs):
        print("call function {}. x={}, y={}".format(fn.__name__, *args, **kwargs))
        ret = fn(*args, **kwargs)    # 解构,闭包(内外层函数的变量;)
        return ret
    return wrapper

@logger    # 等价为  add = logger(add)
def add(x,y): #  z = f(x,y)
    return x+y

ret = add(4, 5)     #   inner(4,5)
print(ret)
--------------------------------------------------------------------------------
call function add. x=4, y=5
9

有关装饰器的4个函数核心概念

1. 在Python语言中,函数也是对象,因此可以用一个变量指向函数。示例如下:

def func(param):
    print('param is : {}'.format(param))

variable = func
variable('函数赋予变量')

# console
param is : 函数赋予变量

2. 函数可作为入参传递给另一个函数。示例如下:

def func(param):
    print('param is : {}'.format(param))

def call(function, param):
    function(param)

call(func, '函数作为入参')

#console
param is : 函数作为入参

3. 函数可以嵌套。示例如下:

def func(param):
    def inner_func(param):
        print('param is : {}'.format(param))
    return inner_func(param)

print(func('函数嵌套'))

# console
param is : 函数嵌套
None

当里面的函数没有return时,运行结果为None。代码如下:

def func(param):
    def inner_func(param):
        print('param is : {}'.format(param))

print(func('函数嵌套'))

# console
None

4. 函数的返回值可以是函数对象。不是内层函数对象的最终返回结果;

def func():
    def inner_func(param):
        print('param is : {}'.format(param))
    return inner_func

res = func()
res('返回函数对象')
print(func())

# console
param is : 返回函数对象
<function func.<locals>.inner_func at 0x10404dcb0>

相关文章

  • 17.2-无参装饰器

    我饿了,你分给我一半面包,这是朋友。你只吃了一口,剩下的面包全给了我 ,这是爱情。你一口没吃,直接把面包给了我 ,...

  • Decorator装饰器

    1. 基本装饰器 1.1. 无参方法无参装饰器 1.2. 有参方法无参装饰器 利用(*args, **kwa...

  • 函数 三

    无参装饰器模板 有参装饰器模板 叠加多个装饰器

  • 第四篇 闭包函数、装饰器、迭代器、序列化

    一、知识储备 二、闭包函数 三、简单装饰器 四、无参装饰器修订 五、无参装饰器之auth 六、有参装饰器 七、加多...

  • Python装饰器

    Python装饰器 一、函数装饰器 1.无参装饰器 示例:日志记录装饰器 2.带参装饰器 示例: 二、类装饰器 示例:

  • 装饰器

    装饰器 decorator类装饰器 带参数的装饰器 举例(装饰器函数;装饰器类;有参与无参) https://fo...

  • decorator-2017-6-6

    Table of Contents 1. 什么是闭包 2. 装饰器 3. 无参装饰器 4...

  • Python无参装饰器

    需求:想要在test_func函数前后执行一些代码 第一步(定义函数,将调用原函数,使用新函数替换) 2.第二 步...

  • 装饰器基础

    一、装饰器概述 装饰器(无参): 它是一个函数 函数作为它的形参 返回值也是一个函数 可以使用@function_...

  • Python-迭代器

    一、装饰器 开放封闭原则 装饰器的简单实现 装饰器语法糖 装饰有参有返的函数 有参装饰器 wraps修改函数文档注...

网友评论

    本文标题:17.2-无参装饰器

    本文链接:https://www.haomeiwen.com/subject/zjkyyctx.html