精华内容
下载资源
问答
  • 其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它 关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的装饰...

    其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它
    关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的装饰器,理解之后,再手写一遍下面的8种装饰器加深理解以后使用就更轻松多了!1.最简单的函数

    def myfunc()
    	print "i am a function"
    
    myfunc()
    


    2.初步了解装饰函数的调用结构
    在函数执行前和执行后分别计时,打印函数运行消耗的时间

    import datetime
    import time
    def out(fun):
    	start = datetime.datetime.now()
    	fun()
    	end = datetime.datetime.now()
    	print (end-start)
    	return fun
    def inner():
        time.sleep(1)
        print ("i am inner func")
    
    myfunc = out
    
    myfunc(inner)
    


    3.尝试引用@语法糖来调用装饰函数

    import datetime,time
    def out(func):
        start =datetime.datetime.now()
        func()
        end = datetime.datetime.now()
        print(end-start)
        return func
    
    @out
    def myfunc():
        time.sleep(1)
        print("zhangkun inner")
    


    4.使用内嵌的包装函数
    使用

    展开全文
  • 主要介绍了python函数装饰器之带参数函数和带参数装饰器用法,结合实例形式分析了Python函数装饰器函数带多个参数以及装饰器带有多个参数的具体原理与实现方法,需要的朋友可以参考下
  • 其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它 关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的...

    其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它
    关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的装饰器,理解之后,再手写一遍下面的8种装饰器加深理解以后使用就更轻松多了!

    1.最简单的函数

    def myfunc()
    	print "i am a function"
    
    myfunc()
    

    2.初步了解装饰函数的调用结构

    在函数执行前和执行后分别计时,打印函数运行消耗的时间

    import datetime
    import time
    def out(fun):
    	start = datetime.datetime.now()
    	fun()
    	end = datetime.datetime.now()
    	print (end-start)
    	return fun
    def inner():
        time.sleep(1)
        print ("i am inner func")
    
    myfunc = out
    
    myfunc(inner)
    

    3.尝试引用@语法糖来调用装饰函数

    import datetime,time
    def out(func):
        start =datetime.datetime.now()
        func()
        end = datetime.datetime.now()
        print(end-start)
        return func
    
    @out
    def myfunc():
        time.sleep(1)
        print("zhangkun inner")
    

    4.使用内嵌的包装函数

    使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象

    import datetime,time
    
    def out(func):
        def inner():
            start = datetime.datetime.now()
            func()
            end = datetime.datetime.now()
            print(end-start)
            print("out and inner")
        return inner
    
    @out
    def myfunc():
        time.sleep(1)
        print("zhangkun")
    
    myfunc()
    

    5.对带参数的函数使用装饰器

    内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象

    import datetime,time
    
    def out(func):
        def inner(*args):
            start = datetime.datetime.now()
            func(*args)
            end = datetime.datetime.now()
            print(end-start)
            print("out and inner")
        return inner
    
    @out
    def myfunc(*args):
        time.sleep(1)
        print("args is{}".format(args))
    
    myfunc("lalalal")
    

    6.给装饰器参数

    和上一示例相比在外层多了一层包装

    #coding:utf-8
    def outermost(*args):
    	def out(func):
    		print ("装饰器参数{}".format(args))
    		def inner(*args):
    			print("innet start")
    			func(*args)
    			print ("inner end")
    		return inner
    	return out
    
    @outermost(666)
    def myfun(*args):
    	print ("试试装饰器和函数都带参数的情况,被装饰的函数参数{}".format(args))
    
    myfun("zhangkun")
    

    7.带类参数的装饰器

    class locker:
        def __init__(self):
            print("locker.__init__() should be not called")
    
        @staticmethod
        def acquire():
            print("locker.acquire() static method be called")
    
        @staticmethod
        def release():
            print("locker.release() static method be called")
    
    def outermost(cls):
        def out(func):
            def inner():
                cls.acquire()
                func()
                cls.release()
            return inner
        return out
    
    @outermost(locker)
    def myfunc():
        print("myfunc called")
    
    myfunc()
    

    8.对一个函数应用多个装饰器

    class mylocker:
        def __init__(self):
            print("mylocker.__init__() called.")
    
        @staticmethod
        def acquire():
            print("mylocker.acquire() called.")
    
        @staticmethod
        def unlock():
            print("  mylocker.unlock() called.")
    
    class lockerex(mylocker):
        @staticmethod
        def acquire():
            print("lockerex.acquire() called.")
    
        @staticmethod
        def unlock():
            print("  lockerex.unlock() called.")
    
    def lockhelper(cls):
        def _deco(func):
            def __deco2(*args, **kwargs):
                print("before %s called." % func.__name__)
                cls.acquire()
                try:
                    return func(*args, **kwargs)
                finally:
                    cls.unlock()
            return __deco2
        return _deco
    
    class example:
        @lockhelper(mylocker)
        @lockhelper(lockerex)
        def myfunc2(self, a, b):
            print(" myfunc2() called.")
            print(a+b)
    
    a = example()
    a.myfunc2(1,2)
    

    9.作为一个类

    虽然装饰器几乎总是可以用函数实现,但是在某些情况下,使用用户自定义的类可能会更好,如果装饰器需要复杂的参数化或者依赖特定状态,那么这种说法往往是对的
    非参数化装饰器用作类的通用模式如下

    class DerocatorAsClass:
        def __init__(self,funcation):
            self.funcation = funcation
    
        def __call__(self, *args, **kwargs):
            # 调用函数之前,做点什么
            result = self.funcation(*args,**kwargs)
            # 在调用之后做点什么并且返回结果
            return result
    
    展开全文
  • 装饰器接收被装饰的函数 def wrapper(*args, **kwargs): # 2. wrapper 接收被装饰函数参数,然后将参数传给被装饰的函数: print(f'wrapper() 接收到位置参数{args}, 关键字参数{kwargs}') start_ti = time....

    实现简单装饰器:

    import time
    
    
    def timer(func):  # 1. 装饰器接收被装饰的函数
    
        def wrapper(*args, **kwargs):  # 2. wrapper 接收被装饰函数的参数,然后将参数传给被装饰的函数:
            print(f'wrapper() 接收到位置参数{args}, 关键字参数{kwargs}')
    
            start_ti = time.time()
            result = func(*args, **kwargs)  # 3. 接收 wrapper 传来的参数并调用被装饰的函数
            total_ti = time.time() - start_ti
            print(f'函数执行耗时 {total_ti} 秒')
            return result
    
        return wrapper
    
    
    @timer
    def demo(n, s=1):
        print(f'Calling demo({n}, {s}) ,现在开始休眠 {n + s} 秒!')
        time.sleep(s + n)
        return 'X'
    
    
    if __name__ == '__main__':
        x = demo(2, s=3)
        print('执行结果:', x)
    wrapper() 接收到位置参数(2,), 关键字参数{'s': 3}
    Calling demo(2, 3) ! 现在开始休眠 5 秒!
    函数执行耗时 5.004848957061768 秒
    执行结果:X

    参数化装饰器:

    装饰器也可以有参数,以下面的代码为例,但是从概念上看 timer 已经不是一个装饰器,而是一个装饰器工厂函数,timer 返回的 decorator 才是真正的装饰器;

    import time
    
    
    def timer(sleep_ti_1, sleep_ti_2=1):  # 1. 接收装饰器的参数
        print(f'timer() 接收到位置参数:{sleep_ti_1} ,关键字参数:{sleep_ti_2}!')
    
        # decorator 才是真正的装饰器
        def decorator(func):  # 2. decorator 接收被装饰的函数
            print(f'decorator() 接收到被装饰的函数:{func}!')
            print(f'decorator 层仍然可以使用 timer 的参数:{sleep_ti_1}, {sleep_ti_2}!')
    
            def wrapper(*args, **kwargs):  # 3. wrapper 接收的是被装饰函数的参数
                print(f'wrapper() 接收到被装饰的函数的位置参数:{args},关键字参数:{kwargs}!')
    
                # 对 wrapper 来说,只有 func 才是自由变量,但是可以用 nonlocal 将 sleep_ti_x 声明为自由变量
                nonlocal sleep_ti_1, sleep_ti_2
                print(f'将 timer 的参数声明为自由变量:{sleep_ti_1}, {sleep_ti_2}!')
    
                start_ti = time.time()
                result = func(*args, **kwargs)  # 4. 接收 wrapper 传来的参数并调用被装饰的函数,
                end_ti = time.time()
                total_ti = end_ti - start_ti
                print(f'函数执行耗时 {total_ti} 秒')
                return result
    
            return wrapper
    
        return decorator
    
    
    @timer(1, 2)
    def demo(n, *, s=1):
        print(f'Calling demo({n}, {s}),现在开始休眠 {n + s} 秒!')
        time.sleep(n + s)
        return 'X'
    
    
    if __name__ == '__main__':
        print('********** Calling __main__ Now **********')
        x = demo(2, s=3)
        print('执行结果:', x)
    
        # 查看 demo 的自由变量
        print(demo.__code__.co_freevars)
    
    
    timer() 接收到位置参数:1 ,关键字参数:2!
    decorator() 接收到被装饰的函数:<function demo at 0x10f3c0378>!
    decorator 层仍然可以使用 timer 的参数:1, 2!
    ********** Calling __main__ Now **********
    wrapper() 接收到被装饰的函数的位置参数:(2,),关键字参数:{'s': 3}!
    将 timer 的参数声明为自由变量:1, 2!
    Calling demo(2, 3),现在开始休眠 5 秒!
    函数执行耗时 5.004558086395264 秒
    执行结果: X
    ('func', 'sleep_ti_1', 'sleep_ti_2')
    
    Process finished with exit code 0
    展开全文
  • 无参装饰器函数和带参装饰器函数

    千次阅读 2016-10-07 15:41:26
    一、无参装饰器函数 Python的 decorator (装饰器) 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。 使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样...

    一、无参装饰器函数

    Python的 decorator (装饰器) 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

    使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。

    例1:

    #!/usr/bin/env python
    #coding=utf-8
    
    #装饰器函数
    def log(f):
        def fn(n):
            print 'call', f.__name__ + '()'
            return f(n)
        return fn
    
    #阶乘函数
    @log
    def factorial(n):
         return reduce(lambda x,y : x*y, range(1,n+1))
    
    print factorial(5)
    结果:


    对于参数只有一个的函数,@log工作的很好,但是当参数不是一个的函数,调用将报错:

    例2:

    #加法函数
    @log
    def add(x, y):
         return x+y
    
    print add(1+2)
    结果:



    因为add()函数需要传入两个参数,但是@log写死了只含一个参数的返回函数。

    所以要让 @log 自适应任何参数定义的函数,可以利用python的*arg 和 **kw,保证任意个数的参数能正常调用。

    例3:

    #!/usr/bin/env python
    #coding=utf-8
    
    #装饰器函数
    def log(f):
        def fn(*args, **kw):
            print 'call', f.__name__ + '()'
            return f(*args, **kw)
        return fn
    
    #阶乘函数
    @log
    def factorial(n):
        return reduce(lambda x,y : x*y, range(1,n+1))
    
    #加法函数
    @log
    def add(x, y):
         return x+y
    
    print add(1, 2)
    print factorial(5)
    结果:



    二、带参数的装饰器函数

    需求来了:

    如果有的函数非常重要,希望打印出'[INFO] call xxx()...',有的函数不太重要,希望打印出'[DEBUG] call xxx()...',这时,

    log函数本身就需要传入'INFO'或'DEBUG'这样的参数,类似这样:

    @log('DEBUG')
    def my_func():
        pass

    翻译成高阶函数相当于:

    my_func = log('DEBUG')(my_func)

    或者:

    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)
    又相当于:

    log_decorator = log('DEBUG')
    @log_decorator
    def my_func():
        pass

    估计看明白了。带参数的装饰器函数其实就是在原来的基础上添加外层函数,又返回内层的装饰器函数而已,也是很简单的。


    总结:带参数的log函数首先返回一个decorator函数,再让这个函数接收decorator函数接收my_func并返回函数。

    代码如下:

    def log(prefix):
        def log_decorator(f):
            def wrapper(*args, **kw):
                print '[%s] %s()...' % (prefix, f.__name__)
                return f(*args, **kw)
            return wrapper
        return log_decorator
    
    @log('DEBUG')
    def test():
        pass
    print test()
    结果:



    无参装饰器函数和有参的装饰器函数就基本上告一段落。









    展开全文
  • 装饰器接收函数作为参数,添加功能后返回一个新函数函数(类),装饰器既可以通过函数去实现,也可以通过类去实现。 Python中通过 @ 使用装饰器 装饰器模式就是通过实现一个装饰器,在不修改原来函数的情况下就...
  • 北京今天天儿不错,在家写点... 使用系统内置的warps装饰器能够使被装饰的函数保留他原始的信息, 直观一点就是在你print(func.__name__)的时候这个函数的名字仍然是func而不是new_func. """ @warps def new...
  • 本文主要介绍的是Python高阶函数与装饰器函数的相关内容,分享给大家,下面话不多说了,来一起看看详细的介绍吧 高阶函数 1、可以使用函数对象作为参数的函数 2、或可以将函数作为返回值的函数 3、函数对象:定义...
  • 1.题目: 2.代码:
  • 1.题目: 2.代码: 3.结果:
  • 1.题目: 2.代码: 补充: isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。 举例:
  • python 类装饰器如何接收request参数

    千次阅读 2018-07-30 10:09:43
    我们在django中想要给类加上装饰器, 又想要用到被装饰函数的request参数 怎么办 ~   我这是用来做权限校验的一个装饰器, 以此为例: class UserAuthentication(object):  def __init__(self, func):  self....
  • Python高阶函数与装饰器函数 高阶函数 1、可以使用函数对象作为参数的函数 2、或可以将函数作为返回值的函数 3、函数对象:定义好的函数,使用函数名调用(不要加括号) #将函数作为参数的高阶函数,通过传入不同...
  • 装饰器为@required_types(int,float)确保函数接收到的 每一个参数都是int或者float类型; # 2). 当装饰器为@required_types(list)确保函数接收到的每一个 参数都是list类型; # 3). 当装饰器为@required_...
  • 函数装饰器

    2019-06-07 19:12:00
    对于某个函数,如果希望在不改变函数代码的前提下,为该函数增加额外的功能,那么可以使用装饰器来装饰该函数。...为了让内函数接收任意类型的参数,将内函数的形参定义为(*args, **kwargs)。在函数中首选完成为...
  • 笔者之前写过一篇简单介绍python函数...本文将介绍装饰器的原理、被装饰函数是如何以参数的形式传入到装饰器函数内部的,以及实现给装饰器函数设定参数参数传递原理。 def decorator(func): def wrapper(*ar...
  • 这段时间一直搞前端模块...注意到在类上添加`@`符号,甚是不解,后来问其它人,才知道这是ES6新增装饰器函数。 它是一种特殊类型的声明,它可以附加到类声明、方法、参数或者属性上。装饰器由`@`符号紧接一个函数名称。
  • 函数参数,万能函数,匿名函数,zip函数,装饰器函数参数1. 位置参数【又称必选参数】2. 关键字参数:3. 默认参数4. 不定长参数万能(参数)函数匿名函数zip函数装饰器复杂点的装饰器 函数参数 1. 位置参数【又称必选...
  • 写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数函数,它返回一个接收函数的的函数。但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函数...
  • Python 装饰器 函数

    千次阅读 2016-04-11 22:01:17
    Python装饰器学习(九步入门):http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 浅谈Python装饰器:https://blog.csdn.net/mdl13412/article/details/22608283 Python装饰器与面向切面编程:...
  • 6 多个装饰器的使用 def make_div(func): """对被装饰的函数的返回值 div标签""" def inner(*args, **kwargs): return "<div>" + func() + "</div>" return inner def make_p(func): """对被装饰...
  • 一、函数式编程 什么是函数式编程? 函数:function 函数式:functional 函数不等于函数式,好比计算不等于计算机   函数式编程的特点: 把计算视为函数而非指令 纯函数式编程:不需要变量,没有副作用,...
  • ``` def process(func,msg): def wrapper(*args,**kwargs): ...我想让process装饰器先判断是否条件成立,再决定是否运行这个函数,但是process中需要msg才能正常运行,如何让process获取到msg呢
  • 1.题目: 2.代码: 3.输出: 补充: isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。 举例:
  • 装饰器是可调用对象,其参数是另一个函数(被装饰的函数),装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或者可调用对象,例如: def deco(func): # 1. 接收被装饰的函数作为参数 def ...
  • python的装饰器函数装饰器

    千次阅读 多人点赞 2019-07-09 09:22:10
    装饰器有很多种,有函数装饰器,也有类的装饰器装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将@装饰器名,放在被装饰对象上面...
  • python中map、reduce、filter、自定义排序函数、装饰器函数和偏函数
  • 在不改变原函数函数调用方式的情况下添加函数功能,我们引入了装饰器装饰器是对函数进行修饰...一、装饰器接收参数 import time import functools def log_kind(kind): #传参数的装饰器 def add_log(fun): ...
  • 函数装饰器装饰器 详解 # import logging # #user_loging接收的是bar函数 # def user_logging(func): # # name接收的是函数调用的时候传入的值“张三” # def wrapper(name,age): # func(name,age) # # #func.__...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,952
精华内容 11,980
关键字:

装饰器函数接收参数