【24】Python装饰器笔记

装饰器
定义:本职是函数,(装饰其他函数)就是为其他函数添加附加功能。
原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰函数的调用的方式

先来一个直观感受
import time
def timmer(func): ##
    def warpper(*args,**kwargs):
        start_time=time.time()
        func()  ##run  test1()
        stop_time=time.time()
        print("the func time is %s"%(start_time-stop_time))
    return warpper

@timmer  #@加函数名,即可调用函数
def test1():  ###源代码
    time.sleep(3)
    print("in the test1")

test1()

实现装饰器的知识储备:
1.函数即"变量"
2.高阶函数
3.嵌套函数(函数里面def声明一个函数叫嵌套函数,调用函数不叫嵌套)

下面进行一波实验:如下三种结果(验证1.函数即“变量”)
A.输出报错没有bar函数
def foo():
    print("in the foo")
    bar()
foo()

B.成功
def bar():
    print("in the bar")
def foo():
    print("in the foo")
    bar()
foo()

C.输出报错,没找到定义的bar函数
def foo():
    print("in the foo")
    bar()
foo()
def bar():
    print("in the bar")

在将函数即“变量”的时候,先讲下python内存存储变量的机制。
当设定一个变量x=1时,内存看成一个大house,这时候大house会腾出一个房间将变量值1放入这个房间,并贴上x的门牌号。
如果是x=1,y=x,那就是变量值1这个房间将会有两个门牌号,即x&y。如图所示:
而在python内存的回收机制中,当你的房间没有门牌号时,它就会默认回收。这样可以节约空间。而当两个或多个变量值都一样时,它不会给你创建N个房间,而是同一个房间内贴上N个门牌号。

凡是也有例外,有人就会说了,那就不会有没有变量名的变量了吗?这个在python中,还真有即匿名函数lambda。当lambda x:x*3,结果是占用的内存地址。

这里的
print(“in the poo”)
bar()
就是函数体相当于变量存放在内存中。poo()就是门牌号,当执行A时之所以会报错,就是因为没有找到bar的函数体。而C虽然定义了bar()但是定义的位置不对,函数都是从上往下读取,当执行poo()之前并没有定义,所以会报错找不到bar

2.高阶函数(又分以下两种)

a:把一个函数名当做实参传递给另外一个函数
import time
def bar():
    time.sleep(3)
    print("in the bar")

def test1(func):  ##根据test1(bar)的调用可以看出,这里的func = bar。这就是把bar函数名传递给func当test1的实参
    start_time=time.time()
    func() #run bar()
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))

test1(bar)

b:返回值中包含函数名
import time
def bar():
    time.sleep(3)
    print("in the bar")
def test2(func):
    print(func)
    return func  #f返回bar的内存值

print(test2(bar))
t=test2(bar) #test2执行结果赋值给了t,相当于把bar(赋值给了t,当使用t()时,就是在执行bar函数
t()  #run bar()

3.嵌套函数 (在一个函数体内用def声明一个函数叫嵌套。调用不叫嵌套)

#局部即变量
def foo():
    def bar():
        print("in the bar")
    bar() ##想要输出print结果就需要一层层的调用
foo()

#局部作用和全局作用域的访问顺序
x=0
def boo():
    def daa():
        x=2
        def son():
            x=3
            print(x)
        son()
    daa()
boo()
猜测下这里的输出结果是:

下面写个简单的装饰器。(高阶函数+嵌套函数=》装饰器)
不设定函数实参

import time
def timer(func):  ##func=test1=test2
    def deco():
        start_time=time.time()
        func()  ##func=test1 =test2
        stop_time=time.time()
        print("the funce run time is %s" %(stop_time-start_time))
    return deco

def test1():
    time.sleep(3)
    print("in the test1")

@timer
def test2():
    time.sleep(3)
    print("in the test2")
test1=timer(test1)
test1() ##-->deco
test2()

当设定test实参时,可以这样写。deco() func()里面都直接*args,***kwargs不限量。如果具体某一个参数,那就可以修改为具体的。

import time
def timer(func):
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print("the funce run time is %s" %(stop_time-start_time))
    return deco

def test1():
    time.sleep(3)
    print("in the test1")

@timer #非固定参数name
def test2(name):
    time.sleep(3)
    print("in the test2",name)

test1=timer(test1)
test1() ##-->deco
test2("alex")

模拟远端登录与本地登录试验:

user,passwd="alex","abc"
def auth(auth_type):
    print("auth>>>",auth_type)
    def outer_wrapper(func):
        def wrapper(*args,**kwargs):
            print("*args,**kwargs",*args,**kwargs)
            if auth_type=="local":
                username=input("Input user: ").strip()
                password=input("Input password: ").strip()
                if username==user and password==passwd:
                    print("\033[32;1mUser has passed authentication\033[0m")
                    res=func(*args,**kwargs)
                    return res
                else:
                    exit("\033[31;1mIminvalid username or password\033[0m")
            elif auth_type=="ldap":
                print("不会")
        return wrapper
    return outer_wrapper
def index():
    print("welcome to index page")
@auth(auth_type="local")  ##本地验证登录
def home():
    print("welcome to home page")
    return  "from home"
@auth(auth_type="ldap")  ##远端验证登录
def dds():
    print("welcome to dds page")

index()
print(home())
dds()

原文地址:http://blog.51cto.com/000011211684/2068714

时间: 2024-11-13 23:10:03

【24】Python装饰器笔记的相关文章

Python装饰器笔记

DRY(Don't Repeat Yourself)原则: 一般是指在写代码的时候尽量避免重复的实现.违反DRY原则导致的坏处很容易理解,例如维护困难,修改时一旦遗漏就会产生不易察觉的问题. 一.函数装饰器 1.从Python内层函数说起 使用内层函数的三个好处 封装 贯彻DRY原则 闭包和工厂函数 1.封装 def outer(num1): def inner_increment(num1): # hidden from outer code return num1 + 1 num2 = in

Python 装饰器笔记

一.装饰器无参数 1.原函数无参数 def wrap_in_tag_b(fn): # wrap_in_tag_b是真正的装饰器 def wrapped(): return "<b>" + fn() + "</b>" return wrapped def wrap_in_tag_i(fn): def wrapped(): return "<i>" + fn() + "</i>" r

Python装饰器的学习笔记(转载)

Python装饰器的学习笔记 2017-05-18 程序员共读 来自:标点符的<Python装饰器的学习笔记> 链接:http://www.biaodianfu.com/python-decorator.html 原文:http://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators-in-python#answer-1594484 装饰器(decorator)是一种高级Python语法.可

python装饰器学习笔记

什么是python装饰器? 装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问. eg:当需要在Func1和Func2中加一样的功能时,可以在outer中添加一次就可以完成全部函数的添加.装饰器与函数建立连接的方式是在函数的前一行用@+装饰器名称来完成.并且在装饰器中一定要返回被装饰的对象 def outer(fun):     def wrapper():         print '验证'         

Python 装饰器学习心得

最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数,这个特殊的功能就是:装饰另一个函数.举一个最简单的例子来说: 1 def identify(f): 2 print 'Decorator identify called.' 3 return f 这里identify其实是一个装饰器,这个装饰器对输入的参数f不进行任何修饰,然后返回这个参数.其中的

python装饰器1

第八步:让装饰器带 类 参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # -*- coding:gbk -*- '''示例8: 装饰器带类参数''' class locker:     def __init__(self):         print("locker.__init__() should be not called.")   

【转】九步学习python装饰器

本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白,对于装饰器我就是用的时候找例子,能蒙对,但是用过之后一段时间就忘了.还是用的少.有空应该好好看一看的,包括闭包.对于各种现代编程语言来说闭包都是很重要的.在这里先谢过原作者,如有侵权请告知. =-=-=-=-=-=-=-=-=-=-一条不怎么华丽的分隔线-=-=-=-=-=-=-=-=-=-= 这

python装饰器Decorators

http://blog.csdn.net/pipisorry/article/details/41902599 Introduction 装饰器Decorators是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能.装饰器用于在不改变原函数代码的情况下修改已存在的函数.常见场景是增加一句

Python装饰器、迭代器&amp;生成器、re正则表达式、字符串格式化

Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########