zoukankan      html  css  js  c++  java
  • python装饰器方法

    前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释。

    今天查看django官网,忽然发现,装饰器用法并不是django框架提供的,而是python的一种语法,真心汗一个,自以为python用的很熟了,看来是井底之蛙!

    恰逢周末,静下心来了解一下python的装饰器方法。

    谈到代码里的装饰器,很自然的想到了设计模式中的装饰器模式,为了防止再次张冠李戴,特意翻了翻设计模式的书,确定python装饰器语法的功能就是类似于装饰器模式要实现的功能。

    关于python装饰器语法,简单的说就是把要执行的方法foo用一段代码包装起来,在调用foo方法的前前后后增加一些逻辑,然后把这个新方法赋给foo。

    也可以在包装的逻辑里写一个封装方法,传入参数,进行一些操作。注意一点,有多个装饰器方法包装foo时,应该是按照从下往上的顺序进行包装。

    def before(pre=''):
        def dec(f):
            def wrapper():
               print pre + " before function"
               f()
            return wrapper
        return dec
    
    def middle(f):
        def wrapper():
            f()
            print "middle function"
        return wrapper
    
    def after(f):
        def wrapper():
            f()
            print "after function"
        return wrapper
    
    def nextbefore(f):
        def wrapper():
            print "nextbefore function"
            f()
        return wrapper
    
    
    
    @middle
    @after
    @nextbefore
    @before("hello")
    def test():
        print "I'm tester"
    
    
    
    if __name__ == '__main__':
        test()

    打印的结果:

    >>> 
    nextbefore function
    hello before function
    I'm tester
    after function
    middle function
    >>> 

    如果被装饰的函数带有参数,则利用装饰器函数内部的wrap函数传参

    def mydecorate(func):
        def wrapper(param):
            print param
            func(param)
        return wrapper
    
    @mydecorate
    def foo1(param):
        print "Hello " + param

    if __name__ == "__main__":
      foo1("Andy")

    返回结果:

    >>> 
    Andy
    Hello Andy

    如果是带有参数装饰器,比如:

    @decorate(arg)

    def foo(param)

    则相当于foo=decorate(arg)(foo), 即装饰器函数decorate(arg)返回结果为一个装饰器,这个装饰器再传入函数参数foo

    def decorate1(para):
        def real_decorate(func):
            print para
            def wrapper(ff):   
                func(ff)
            return wrapper
        return real_decorate
    
    @decorate1("hello")
    def foo(username):
        print "welcome " + username;
    
    if __name__ == "__main__":
        foo("Andy")

    返回结果:

    >>> 
    hello
    welcome Andy
    >>> 

    如果带参数的装饰器还有装饰器,则等同于 foo=decorate2(decorate1(arg)(foo)) or foo=decorate2(arg1,arg2)(decorate1(arg)(foo))

  • 相关阅读:
    setHapticFeedbackEnabled在androi的作用
    Android 跑马灯
    jQuery中绑定事件的命名空间详解
    可见即所得的CSS编辑设计
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    用到的知识点
    用PS去除图片中文字的6个方法
    html页面头部里的meta
    px pt em对应关系
    phpMyAdmin安装与配置(涉及LAMP配置)
  • 原文地址:https://www.cnblogs.com/zhq1007/p/4457940.html
Copyright © 2011-2022 走看看