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. WinForm中ClickOnce发布至广域网

    ClickOnce智能客户端,是微软提供比较早的一项技术,用于实现WinForm开发的应用程序能够自动更新,省去给每台客户端升级带来的困扰. 从网上的贴子里看,有的说好用,有的说不好用.客观的说,微软 ...

  2. statement preparestatement CallableStatement

    大家都知道Statement.PrepareStatement 和CallableStatement 对象,其实它们是interface,为什么JDBC2.0中要提供这三个对象呢?对于Statemen ...

  3. centos/linux下的安装mysql

    1.从yum 下面下载mysql数据库 yum -y install mysql-server 2.查询该mysql是否安装完成 rpm -qa|grep mysql-server 出现如下图所示标明 ...

  4. mac中配置jdk环境

  5. c中有序表的简单定义

    #include <iostream> using namespace std; #define MaxSize 50 typedef int ElemType; //定义变量int的别名 ...

  6. hdu1496 打表

    通常可以想到直接四个for枚举,但是会超时.就算只用三个for也很危险.可以用打表的方法将时间复杂度降到O(n^2),注意到x1,x2,x3,x4的取值区间是关于零对称的,因此可以只考虑正整数部分,洗 ...

  7. 转 Caffe学习系列(9):运行caffe自带的两个简单例子

    为了程序的简洁,在caffe中是不带练习数据的,因此需要自己去下载.但在caffe根目录下的data文件夹里,作者已经为我们编写好了下载数据的脚本文件,我们只需要联网,运行这些脚本文件就行了. 注意: ...

  8. java.sql.SQLException:No suitable driver found for http://localhost:3306/school

    1.错误描述 java.sql.SQLException:No suitable driver found for http://localhost:3306/school 2.错误原因 Class. ...

  9. Linux显示用户的ID

    Linux显示用户的ID youhaidong@youhaidong-ThinkPad-Edge-E545:~$ id uid=1000(youhaidong) gid=1000(youhaidong ...

  10. Linux显示USB设备

    Linux显示USB设备 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ lsusb -tv /: Bus 08.Port 1: Dev 1, Class=ro ...