1. 定义:
    1. 装饰器本身就是一个函数
    2. 为其他函数提供附加功能
      1. 不改变源代码
      2. 不改变原调用方式
    3. 装饰器=高阶函数+嵌套函数
  2. 知识点:
    1. 函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) )
    2. 高阶函数
      1. 把函数名当成一个实参传递给另一个函数func(test1) (不改变源代码的前提下添加代码)
      2. 返回值中包含函数名return deco (不改变函数的调用方式)
    3. 嵌套函数:函数中加入新的函数def func1(): def func2():
  3. 典型结构:   
 def func1(test):
def deco():
#progress
return deco#返回函数的地址,达到不改变调用方式的目的

完整程序:

# __Author__Panda-J____

import time

def timer(func):  # for test1 & 2
start_time = time.time()
func() # run func and test its running time
end_time = time.time()
print("this func running time is %s" % (end_time - start_time))
return func @timer
def test1():
time.sleep(1)
print("this is test1") @timer
def test2():
time.sleep(1)
print("this is test2") test1()
test2()

带参数的装饰器:

 # __Author__Panda-J____

 import time

 def timer(func):  # for test1 & 2
def deco(*args,**kwargs):#不定参数
start_time = time.time()
func(*args,**kwargs) # run func and test its running time
end_time = time.time()
print("this func running time is %s" % (end_time - start_time))
return deco @timer
def test1():
time.sleep(1)
print("this is test1") @timer
def test2(arg1):
time.sleep(1)
print("this is test2,",arg1) print(test1())
test2("name")

  本段程序的结果是

this is test1
this func running time is 1.000265121459961
None
this is test2, name
this func running time is 1.0000722408294678

  问题:

  1 为什么print(test1)会为None,原因是因为在装饰器中没有返回(return)任何数值给到test1中。没有可以打印的内容。

  2 在28行中,test2有一个位置参数name传给了装饰器deco中,此处的arg=“name”

如果装饰器本身也带参数的情况:

    需求:三层网页,分别为index,home,bbs。在登陆home和bbs页面的时候需要输入不同的用户名和密码,正确方可运行对应函数。

    思路

      1. 定义三个函数
      2. 加装饰器
      3. 用不同的用户名和密码(一个为本地Local,一个为ldap)

完整程序

# __Author__Panda-J____
#语法糖 import time
user="jiang"
pssw="123"
def auth(auth_type):#多加了一层函数进行关键字嵌套
print("auth func is",auth_type)
def outer_wrapper(func):#相当于没有装饰器参数时候的那一层
def wrapper(*args,**kwargs):#进行函数的装饰
if auth_type=="local":#使用本地用户名和密码
user_name=input("user_name:").strip()
password=input("paassword:").strip()
if user_name==user and password==pssw:#判定用户名和密码驶入正确
print("\033[32;1mUser authorized\033[0m")
return func(*args, **kwargs)#返回函数进行打印,如果没有这一行,不会执行home和bbs函数中的打印程序,home()将为None,因为没有返回任何内容
else:#用户名和密码输入不正确
exit("\033[31;1mUser failed\033[0m")
elif auth_type=="ldap":#使用ldap的密码
print("plz use ldap password")
return wrapper
return outer_wrapper
def index():
print("welcome index")
@auth(auth_type="local")#home
def home():
print("welcome home")
return "home is best"
@auth(auth_type="ldap")
def bbs():
print("welcome bss") index()
print(home())
bbs()

我所能理解的装饰器的应用场景和关键知识点都归纳了,欢迎各位指正。

         

Python中装饰器的用法的更多相关文章

  1. 8.Python中装饰器是什么?

    Python中装饰器是什么? A Python decorator is a specific change that we make in Python syntax to alter functi ...

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

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

  3. Python核心技术与实战——十四|Python中装饰器的使用

    我在以前的帖子里讲了装饰器的用法,这里我们来具体讲一讲Python中的装饰器,这里,我们从前面讲的函数,闭包为切入点,引出装饰器的概念.表达和基本使用方法.其次,我们结合一些实际工程中的例子,以便能再 ...

  4. Python函数装饰器高级用法

    在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...

  5. python中装饰器的原理以及实现,

    python版本 3.6 1.python的装饰器说白了就是闭包函数的一种应用场景,在运用的时候我们遵循 #开放封闭原则:对修改封闭,对拓展开放 2.什么是装饰器 #装饰他人的器具,本身可以是任意可调 ...

  6. Python中装饰器(转)

    本文由 伯乐在线 - 7even 翻译,艾凌风 校稿.未经许可,禁止转载!英文出处:Simeon Franklin.欢迎加入翻译组. 好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生 ...

  7. python中装饰器修复技术

    python装饰器@wraps作用-修复被装饰后的函数名等属性的改变 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变), 为了 ...

  8. python中装饰器的执行细节

    本文代码借用 廖雪峰的python教程(官网:http://www.liaoxuefeng.com/) 不了解装饰器的可以先看教程 直接上带参数装饰器的代码 def log(text): def de ...

  9. python中装饰器(语法糖)概念

    “”“” 什么是装饰器? """ 还是通过一个例子来慢慢说明 先看下面的例子 def func_1(x): return x*2 def fun_2(x): return ...

随机推荐

  1. [SDOI2015]序列统计

    [SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...

  2. bzoj 1814 Ural 1519 Formula 1 插头DP

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 942  Solved: 356[Submit][Sta ...

  3. Angular4.0用命令行创建组件服务出错

    之前使用cnpm创建的angular4.0项目,由于cnpm下载的node_modules资源经常会有部分缺失,所以在用命令行创建模板.服务的时候会报错: Error: ELOOP: too many ...

  4. Centos下_MysqL5.7在使用mysqldump命令备份数据库报错:mysqldump: Got error: 1449: The user specified as a definer ('fk_system'@'localhost') does not exist when using LOCK TABLES

    在阿里云服务器增加一个shell脚本定时备份数据库脚本执行任务时,测试性的执行了备份命令,如下 [root@iZ2ze503xw2q1fftv5rhboZ mysql_bak]# /usr/local ...

  5. hihoCoder 403 Forbidden 字典树

    题意:给定个规则,个ip,问这些ip是否能和某个规则匹配,如果有多个规则,则匹配第一个.如果没能匹配成功,则认为是"allow",否则根据规则决定是"allow" ...

  6. Docker系列一:Docker基本概念及指令介绍

    1. Docker是什么? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用 ...

  7. 项目实战14—ELK 企业内部日志分析系统

    一.els.elk 的介绍 1.els,elk els:ElasticSearch,Logstash,Kibana,Beats elk:ElasticSearch,Logstash,Kibana ① ...

  8. Wireshark抓包常见出现错误

    转自这里 1.   tcp out-of-order(tcp有问题) 解答: 1).    应该有很多原因.但是多半是网络拥塞,导致顺序包抵达时间不同,延时太长,或者包丢失,需要重新组合数据单元 因为 ...

  9. 关于chrom开发者工具priview和respons 数据内容不一致问题

    在昨天晚上2017年8月24日,深夜升级的时候发现你了一个问题:简单的把问题描述一下:新增的一个付款单中的金额为最大值9999999999999999 ,但是保存后返回来的却是100000000000 ...

  10. 【转载】Ubuntu环境下安装QT(转)

    Ubuntu 安装 Qt 开发环境 简单实现是本文要介绍的内容,内容很短,取其精华,详细介绍Qt 类库的说明,先来看内容. 一.Ubuntu下安装Qt $ sudo apt-get install q ...