摘要:装饰器基础本质本质是语法糖使用来修饰某个函数时其解释器会解释成注意这条语句会被执行多重装饰器相当于带参数装饰器相当于使用给被装饰函数传递参数是一个数组,一个字典带参数的装饰器等同于方法装饰器类方法是一个特殊的函数,它的第一个参数指向类实例
python decorators 装饰器基础 Decorator 本质
@ 本质是语法糖- Syntactic Sugar
使用@decorator 来修饰某个函数 func 时:
@decorator def func(): pass
其解释器会解释成:
func = decorator(func)
注意这条语句会被执行
多重装饰器
@decorator_one @decorator_two def func(): pass
相当于:
func = decorator_one(decorator_two(func))
带参数装饰器
@decorator(arg1, arg2) def func(): pass
相当于:
func = decorator(arg1,arg2)(func)使用 *args、**kwargs 给被装饰函数传递参数
def wrapper(func): def wrapper_in(*args, **kwargs): # args是一个数组,kwargs一个字典 print("%s is running" % func.__name__) return func(*args, **kwargs) return wrapper_in @wrapper def func(parameter1, parameter2, key1=1): print("call func with {} {} {}".format(parameter1, parameter2, key1)) func("haha", None, key1=2) # func is running # call func with haha None 2带参数的装饰器
def log(level): def decorator(func): def wrapper(*args, **kwargs): if level == "warn": print("%s with warn is running" % func.__name__) elif level == "info": print("%s with info is running" % func.__name__) return func(*args, **kwargs) return wrapper return decorator @log("warn") def foo(*args, **kwargs): print("args {}, kwargs{}".format(args, kwargs)) foo(1, 2, a = 3) # foo with warn is running # args (1, 2), kwargs{"a": 3}
等同于
def foo(name="foo"): print("args {}, kwargs{}".format(args, kwargs)) foo = log("warn")(foo)方法装饰器
类方法是一个特殊的函数,它的第一个参数 self 指向类实例
所以我们同样可以装饰类方法
def decorate(func): def wrapper(self): return "{0}
".format(func(self)) return wrapper class Person(object): def __init__(self): self.name = "John" self.family = "Doe" @decorate def get_fullname(self): return self.name+" "+self.family my_person = Person() print my_person.get_fullname() #John Doe
上例相当于固定了 self 参数,不太灵活
使用 *args, **kwargs传递给 wrapper 更加通用:
def pecorate(func): def wrapper(*args, **kwargs): return "类装饰器{0}
".format(func(*args, **kwargs)) return wrapper class Person(object): def __init__(self): self.name = "John" self.family = "Doe" @pecorate def get_fullname(self): return self.name+" "+self.family my_person = Person() print my_person.get_fullname()
类实现 __call__ 方法后变成可调用对象,故可以用类做装饰器
class EntryExit(object): def __init__(self, f): self.f = f def __call__(self): print "Entering", self.f.__name__ self.f() print "Exited", self.f.__name__ @EntryExit def func1(): print "inside func1()" @EntryExit def func2(): print "inside func2()" def func3(): pass print type(EntryExit(None)) # func1 变为类实例 print type(func1) print type(EntryExit) # func3 是普通函数 print type(func3) func1() func2() ## # # # Entering func1 # inside func1() # Exited func1 # Entering func2 # inside func2() # Exited func2
类装饰器
@EntryExit def func1(): print "inside func1()"
等同于
def func1(): print "inside func1()" # 此处可以看出 func1 是类EntryExit的一个实例 func1 = EntryExit(myfunc1)装饰器装饰类
register_handles = [] def route(url): global register_handles def register(handler): register_handles.append((".*$", [(url, handler)])) return handler return register @route("/index") class Index(): def get(self, *args, **kwargs): print("hi") # Index 仍然为原来定义的类实例 # 相当于在定义类的同时调用装饰器函数 route, 将该类注册到全局路由 register_handles @route("/main") class Main(): def get(self, *args, **kwargs): print("hi") print (register_handles) print(type(Index)) # [(".*$", [("/index",)]), (".*$", [("/main", )])] #
@route("/index") class Index(): def get(self, *args, **kwargs): print("hi")
Index = route("/index")(Index) # register 返回传入的 handler,故 Index 仍然为类对象functools
上述装饰器实现有个问题,就是被装饰函数的属性被改变
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42700.html
摘要:装饰器传参被装饰的函数带有参数的情况接上一篇,直接上代码函数也就是被装饰的函数的运行时间是装饰器的正确使用,不需要传参装饰器的正确使用,需要传参此时不用再像上面一样赋值,可以直接调用返回值被装饰的函数有返回值在装饰器内部需被装饰函数的调用 python 装饰器 传参 被装饰的函数带有参数的情况 接上一篇,直接上代码 import time def decorator(func): ...
一、前提概念 Python中的函数是对象。也因此,函数可以被当做变量使用。 二、代码模型 以下代码片段来自于: http://www.sharejs.com/codes/python/8361 # -*- coding: utf-8 -*- from threading import Thread import time class TimeoutEx...
摘要:装饰器是可调用的对象,其参数是另一个函数被装饰的函数。第二大特性是,装饰器在加载模块时立即执行。另一个常见的装饰器是,它的作用是协助构建行为良好的装饰器。 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。 装饰器基础知识 首先看一下这段代码 def deco(fn): print I am %s! % fn.__name__ @deco def func(): ...
摘要:使用类装饰器,优点是灵活性大,高内聚,封装性。不过不用担心,有,本身也是一个装饰器,它的作用就是把原函数的元信息拷贝到装饰器函数中,使得装饰器函数也有和原函数一样的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一。...
摘要:为了避免重复调用,可以适当地做缓存,的装饰器可以完美的完成这一任务。这意味着我们可以为方法创建装饰器,只是要记得考虑。装饰器封装了函数,这使得调试函数变得困难。另外,使用装饰器去管理缓存和权限。 原文地址 之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢。 def fib_direct(n): assert n > 0, invalid n ...
阅读 1715·2021-11-25 09:43
阅读 15099·2021-09-22 15:11
阅读 2605·2019-08-30 13:19
阅读 1982·2019-08-30 12:54
阅读 1801·2019-08-29 13:06
阅读 906·2019-08-26 14:07
阅读 1597·2019-08-26 10:47
阅读 3006·2019-08-26 10:41