一、定义

器即函数

装饰即修饰,意指为其他函数添加新功能

装饰器定义:本质就是函数,功能是为其他函数添加新功能

原则:

  • 1.不修改被装饰函数的源代码(开放封闭原则)

  • 2.为被装饰函数添加新功能后,不修改被修饰函数的调用方

二、装饰器=高阶函数+函数嵌套+闭包

1. 高阶函数

默认满足以下两个条件中的一个就是高阶函数:

  • 函数的传入参数是一个函数名
  • 函数的返回值是一个函数名
#高阶函数应用1:把函数当做参数传给高阶函数
import time
def foo():
print('from the foo') def timmer(func):
start_time=time.time()
func()
stop_time=time.time()
print('函数%s 运行时间是%s' %(func,stop_time-start_time))
timmer(foo)
#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式 #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
import time
def foo():
print('from the foo') def timmer(func):
start_time=time.time()
return func
stop_time=time.time()
print('函数%s 运行时间是%s' %(func,stop_time-start_time))
foo=timmer(foo)
foo()
#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能 函数返回值是函数名

2. 函数嵌套

在函数内部定义函数

3. 闭包

闭包:在一个作用域里放入定义变量,相当于打了一个包

三、装饰器实现

def timmer(func):
def wrapper(*args, **kwargs):
print(func)
res = func(*args, **kwargs)
return res return wrapper @timmer # test = timmer(test)
def test(name, age):
print('姓名:%s,年龄:%s' % (name, age))
return 1 msg = test('Tom', 18) # 就是在运行wrapper
print(msg)

四、应用

网站登录认证

 user_list = [
{'name': 'alex', 'passwd': ''},
{'name': 'Tom', 'passwd': ''},
{'name': 'Jerry', 'passwd': ''}
] current_user = {'username': None, 'login': False} def auth_deco(func):
def wrapper(*args, **kwargs):
if current_user['username'] and current_user['login']:
res = func(*args, **kwargs)
return res
i = 0
while i < 3:
username = input('用户名: ').strip()
passwd = input('密码: ').strip()
for user_dic in user_list:
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username'] = username
current_user['login'] = True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误,重新登录')
i += 1
print('请稍后重试') return wrapper @auth_deco
def index():
print('欢迎来到主页面') @auth_deco
def home():
print('这里是你家') @auth_deco
def shopping_car():
print('查看购物车啊亲') @auth_deco
def order():
print('查看订单啊亲') home()

无参装饰器

 user_list = [
{'name': 'alex', 'passwd': ''},
{'name': 'Tom', 'passwd': ''},
{'name': 'Jerry', 'passwd': ''}
] current_user = {'username': None, 'login': False} def auth(auth_type='file'):
def auth_deco(func):
def wrapper(*args, **kwargs):
if auth_type == 'file':
if current_user['username'] and current_user['login']:
res = func(*args, **kwargs)
return res
i = 0
while i < 3:
username = input('用户名: ').strip()
passwd = input('密码: ').strip()
for user_dic in user_list:
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username'] = username
current_user['login'] = True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误,重新登录')
i += 1
print('请稍后登录')
elif auth_type == 'ldap':
print('巴拉拉小魔仙')
res = func(*args, **kwargs)
return res return wrapper return auth_deco # auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
# 就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
@auth(auth_type='ldap')
def index():
print('欢迎来到主页面') @auth(auth_type='ldap')
def home():
print('这里是你家') @auth(auth_type='file')
def shopping_car():
print('查看购物车啊亲') @auth(auth_type='file')
def order():
print('查看订单啊亲') order()

有参装饰器

五、类的装饰器

装饰器不仅可以对函数进行装饰,还可以装饰类

def deco(obj):
print('====')
obj.x = 1
obj.y = 2
return obj @deco
class Foo(object):
pass print(Foo.__dict__)
# {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>,
# '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}

Python-12-装饰器的更多相关文章

  1. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  2. 如何用python的装饰器定义一个像C++一样的强类型函数

        Python作为一个动态的脚本语言,其函数在定义时是不需要指出参数的类型,也不需要指出函数是否有返回值.本文将介绍如何使用python的装饰器来定义一个像C++那样的强类型函数.接下去,先介绍 ...

  3. Python的装饰器实例用法小结

    这篇文章主要介绍了Python装饰器用法,结合实例形式总结分析了Python常用装饰器的概念.功能.使用方法及相关注意事项 一.装饰器是什么 python的装饰器本质上是一个Python函数,它可以让 ...

  4. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  5. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  6. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  7. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  8. 两个实用的Python的装饰器

    两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...

  9. python 基础——装饰器

    python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...

  10. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

随机推荐

  1. 动手动脑---找出指定文件夹下所有包容指定字符串的txt文件

    思路:先判断是否为文件,如果是文件,则需要判断改文件名是否包含字符串"txt",包含则输出.如果是文件夹的话,先需要判断文件名是否包含".txt"(因为文件名也 ...

  2. c++ socket发送数据时,sendData = char * string 导致的乱码问题

    解决方法:将string 通过copy函数复制到某个char[] 1. string res =“xxx”; char arr[100]; int len = res.copy(arr, 100); ...

  3. 洛谷 P3371 【模板】单源最短路径(弱化版) 题解

    P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...

  4. Web前端鼠标悬停实现显示与隐藏效果

    css定义,偏移量,相对定位,绝对定位 显示与隐藏 二维码相对于微信图标定位 鼠标悬停微信图标上显示 鼠标离开微信图标时隐藏 什么是定位,就是定义网页标签在运行时显示的位置 css提供Position ...

  5. Hungry Canadian

    Hungry Canadian(简单dp) 具体见代码注释 #include <iostream> #include <cstdio> #include <cstring ...

  6. ajax post data 获取不到数据,注意 content-type的设置 、post/get(转)

    ajax post  data  获取不到数据,注意 content-type的设置 .post/get 关于 jQuery data 传递数据.网上各种获取不到数据,乱码之类的. 好吧今天我也遇到了 ...

  7. react用脚手架创建一个react单页面项目,react起手式

    官网地址:https://react.docschina.org/ 确保本地安装了Node.js node的版本大于8.10    npm的版本大于5.6 1.在本地的某个位置创建一个文件夹,执行以下 ...

  8. nacos启动与sql8.0的问题解决方法

    hi all! 半年多没更新,是不是以为我消失了……直接正题~ 在搭建nacos环境的时候,有这样的一项:数据库持久化配置.(官方文档),这个配置可以灵活的帮我们进行配置而不用总是重启服务. 那么问题 ...

  9. from bs4 import BeautifulSoup 引入需要安装的文件和步骤

    调用beautifulsoup库时,运行后提示错误: ImportError: No module named bs4 , 意思就是没有找到bs4模块,所以解决方法就是将bs4安装上,具体步骤如下: ...

  10. unused function warning message(转)

    這篇的對象是 static function,static function 若沒有其它 function 去存取的話,在 compile 時,會發生 unused error,可以在 functio ...