zoukankan      html  css  js  c++  java
  • python中decorator的用法及原理(一)

    0、 概念

    什么叫装饰器,其实也可以叫做包装器。即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来。

    Python中的装饰器分为两类:函数装饰器和类装饰器。

    这里我们先讨论函数装饰器。

    1. 不带参数的decorator

    (1) 基本用法:

        def decorator1(func):  
            def dec(*args):  
                print 'pre action'  
                result = func(*args)  
                print 'post action'  
                return result  
            return dec  
         
        @decorator1  
        def test_f1(name):  
            print name  
            return None  
          
        test_f1('name1') #out: preaction/name1/post action  
        test_f1('name2') #out: preaction/name2/post action  

    (2) 这种现象的内部原理:

    在python内部,当你做了这件事情:

        @decorator1  
        def test_f1(name):  

    其实就是 test_f1 = decorator1(test_f1) #即test_f1作为参数传递给func。

    此后的test_f1是装饰器中的dec函数对象了,而不是原来的函数的名称。当调用test_f1(‘name1’)的时候,其实调用的是dec(‘name1’)函数,而在dec函数内部,又调用了func,这样就造成了装饰器的效果。

    这也解释了func是被装饰函数,*arg是被装饰函数的参数—这种现象了。

    2. 带参数的decorator

    (1) 基本用法:

        def wap(name):  
            def decorator1(func):  
                def dec(*args):  
                    print name  
                    print 'pre action'  
                    result = func(*args)  
                    print 'post action'  
                    return result  
                return dec  
            return decorator1  
         
        @wap('f1')  
        def test_f1(name):  
            print name  
            return None  
         
        @wap('f2')  
        def test_f2(name):  
            print name  
            return None  
          
        test_f1('name1') #out: f1/pre action/name1/post action  
        test_f2('name2') #out: f2/pre action/name2/post action  

    带参数的decorator,作用是通过传递参数可以定制不同的装饰器。

    (2) 内部原理

    这里和上面 不带参数的decorator类似,

        @wap('f1')  
        def test_f1(name):  

    内部逻辑为: test_f1 = wap(‘f1’)(test_f1)

    这里wap(‘f1’)返回是decorator1函数对象,这样的 话,wap(‘f1’)(test_f1)其实就是decorator1(test_f1),这样就和上面的一样了。只不过这里传递了一个参数’f1’进 入decorator内部,使得我们可以操作这个参数。

    3. 函数decorator也可以修饰类成员函数

        class FOO:  
            @decorator1  
            def fun(self):  
                print self.name  

    注意此时fun的self会被传递到decorator1中。此时把self看做普通的函数入参。 而且如果要使用class的属性的话,定义fun时必须带有self参数。

  • 相关阅读:
    hadoop运维
    HBase Master启动过程
    bulk-load 装载HDFS数据到HBase
    HBase开启LZO
    Hash函数
    swift菜鸟入门视频教程-02-基本运算符
    当当网-前端project师測试题
    VB.NET & DataGridView与数据库的连接
    Hadoop-2.2.0中文文档—— Common
    PHP 获取数组随意下标key的上一个prev和下一个next下标值
  • 原文地址:https://www.cnblogs.com/welhzh/p/6733700.html
Copyright © 2011-2022 走看看