美文网首页
[python]返回函数和装饰器

[python]返回函数和装饰器

作者: 喵吉呀呀 | 来源:发表于2019-04-08 14:56 被阅读0次
返回函数

返回函数: 函数作为结果返回
e.g:

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

f = lazy_sum(1,2)   # 调用lazy_sum并传参,实质是把sum赋值给f
f()  # 调用
#  这两行相当于lazy_sum(1,2)()
3

>每次调用都会返回一个新的函数,即使传入相同的参数:

f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
f1==f2
>>>False
装饰器(decorator)

补充知识:
函数对象有一个name属性
e.g:

def now():
    print('2015-3-25')
f = now
now.__name__
>>>'now'
f.__name__
>>>'now'

装饰器写法:
@funcName
e.g:

def print_caller(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

def test():
    print('test')

@print_caller
test()

>>>call test():
>>>test

decorator实质是返回一个函数,所以,原来的test()函数仍然存在,只是现在同名的test变量指向了新的函数,于是调用test()将执行新函数,即在print_caller()函数中返回的wrapper()函数。
wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。
所以,@print_caller相当于执行了:

test = print_caller(test)

打印函数执行前后时间的example:

def metric(func):
    def decorator(*args, **kw):
        print('start:%s' % int(time.time()))
        time.sleep(2)
        r = func(args, **kw)
        print('end:%s' % int(time.time()))
        return r
    return decorator

@metric
def test(a):
    print('test')

test()

>>>start:1554695731
>>>test
>>>end:1554695733

上述几个例子都是decorator不需传参数的情况,如果decorator需要传参数,就需要编写一个返回decorator的高阶函数
e.g:

def add_text(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('text:%s' % text)
            r = func(args, **kw)
            return r
        return wrapper
    return decorator


@add_text('miao')
def test(a):
    print('test')

>>>text:miao
>>>test

实质是三层的嵌套,@add_text相当于执行了:

test = add_text('miao')(test)

*decorator本质的嵌套返回函数,会导致原型指针发生变化,name等属性也随之发生变化,如上述的name会从test变成wrapper,理论上应该添加一句wrapper.name = func.name,把原型指针指针原函数,但Python存在内置的functools.wraps做了这个处理

import functools

# 不带参数的装饰器
def print_caller(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

# 带参数的装饰器
def add_text(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('text:%s' % text)
            r = func(args, **kw)
            return r
        return wrapper
    return decorator

相关文章

  • Python装饰器3-返回函数

    函数返回值是函数 小结 Python装饰器本质也是返回一个函数地址,然后运行时发生函数调用

  • python装饰器

    装饰器简述 要理解装饰器需要知道Python高阶函数和python闭包,Python高阶函数可以接受函数作为参数,...

  • python装饰器2018-11-19

    装饰器也是个函数 装饰器有参数,参数是函数 装饰器有内嵌函数 装饰器有返回值,返回值是内嵌函数 装饰器使用时直接挂...

  • (五) 学习笔记:python的装饰器,生成器和迭代器

    装饰器 装饰器本质是一个python函数,它可以在让其他函数不需要任何代码变动的前提下增加额外的功能,装饰器的返回...

  • [python]返回函数和装饰器

    返回函数 返回函数: 函数作为结果返回e.g: >每次调用都会返回一个新的函数,即使传入相同的参数: 装饰器(de...

  • 函数装饰器(Function Decorators)

    函数装饰器(Function Decorators) python中函数装饰器的使用和Java中注解类似, 直接在...

  • 装饰器

    1、装饰器引入 Python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数...

  • 装饰器(decorator)

    什么是装饰器 python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,...

  • 理解 Python 装饰器与回调函数

    1.理解 Python 装饰器2.Python装饰器和回调函数回调函数就是一个通过函数指针调用的函数。如果你把函数...

  • 装饰器

    装饰器概念 用与拓展原来函数功能的一种函数, 这个函数的特殊之处在于它的返回值是一个函数,使用python装饰器的...

网友评论

      本文标题:[python]返回函数和装饰器

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