这是在Python学习小组上介绍的内容,现学现卖、多练习是好的学习方式。

第一步:最简单的函数,准备附加额外功能

1
2
3
4
5
6
7
8
# -*- coding:gbk -*-
'''示例1: 最简单的函数,表示调用了两次'''
def myfunc():
    print("myfunc() called.")
myfunc()
myfunc()

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding:gbk -*-
'''示例2: 替换函数(装饰)
装饰函数的参数是被装饰的函数对象,返回原函数对象
装饰的实质语句: myfunc = deco(myfunc)'''
def deco(func):
    print("before myfunc() called.")
    func()
    print("  after myfunc() called.")
    return func
def myfunc():
    print(" myfunc() called.")
myfunc = deco(myfunc)
myfunc()
myfunc()

第三步:使用语法糖@来装饰函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding:gbk -*-
'''示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''
def deco(func):
    print("before myfunc() called.")
    func()
    print("  after myfunc() called.")
    return func
@deco
def myfunc():
    print(" myfunc() called.")
myfunc()
myfunc()

第四步:使用内嵌包装函数来确保每次新函数都被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:gbk -*-
'''示例4: 使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
    def _deco():
        print("before myfunc() called.")
        func()
        print("  after myfunc() called.")
        # 不需要返回func,实际上应返回原函数的返回值
    return _deco
@deco
def myfunc():
    print(" myfunc() called.")
    return 'ok'
myfunc()
myfunc()

第五步:对带参数的函数进行装饰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:gbk -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
    def _deco(a, b):
        print("before myfunc() called.")
        ret = func(a, b)
        print("  after myfunc() called. result: %s" % ret)
        return ret
    return _deco
@deco
def myfunc(a, b):
    print(" myfunc(%s,%s) called." % (a, b))
    return a + b
myfunc(1, 2)
myfunc(3, 4)

第六步:对参数数量不确定的函数进行装饰

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
# -*- coding:gbk -*-
'''示例6: 对参数数量不确定的函数进行装饰,
参数用(*args, **kwargs),自动适应变参和命名参数'''
def deco(func):
    def _deco(*args, **kwargs):
        print("before %s called." % func.__name__)
        ret = func(*args, **kwargs)
        print("  after %s called. result: %s" % (func.__name__, ret))
        return ret
    return _deco
@deco
def myfunc(a, b):
    print(" myfunc(%s,%s) called." % (a, b))
    return a+b
@deco
def myfunc2(a, b, c):
    print(" myfunc2(%s,%s,%s) called." % (a, b, c))
    return a+b+c
myfunc(1, 2)
myfunc(3, 4)
myfunc2(1, 2, 3)
myfunc2(3, 4, 5)

第七步:让装饰器带参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding:gbk -*-
'''示例7: 在示例4的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''
def deco(arg):
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, arg))
            func()
            print("  after %s called [%s]." % (func.__name__, arg))
        return __deco
    return _deco
@deco("mymodule")
def myfunc():
    print(" myfunc() called.")
@deco("module2")
def myfunc2():
    print(" myfunc2() called.")
myfunc()
myfunc2()

第八步:让装饰器带 类 参数

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.")
         
    @staticmethod
    def acquire():
        print("locker.acquire() called.(这是静态方法)")
         
    @staticmethod
    def release():
        print("  locker.release() called.(不需要对象实例)")
def deco(cls):
    '''cls 必须实现acquire和release静态方法'''
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, cls))
            cls.acquire()
            try:
                return func()
            finally:
                cls.release()
        return __deco
    return _deco
@deco(locker)
def myfunc():
    print(" myfunc() called.")
myfunc()
myfunc()

第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器

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
35
36
# -*- coding:gbk -*-
'''mylocker.py: 公共类 for 示例9.py'''
class mylocker:
    def __init__(self):
        print("mylocker.__init__() called.")
         
    @staticmethod
    def acquire():
        print("mylocker.acquire() called.")
         
    @staticmethod
    def unlock():
        print("  mylocker.unlock() called.")
class lockerex(mylocker):
    @staticmethod
    def acquire():
        print("lockerex.acquire() called.")
         
    @staticmethod
    def unlock():
        print("  lockerex.unlock() called.")
def lockhelper(cls):
    '''cls 必须实现acquire和release静态方法'''
    def _deco(func):
        def __deco(*args, **kwargs):
            print("before %s called." % func.__name__)
            cls.acquire()
            try:
                return func(*args, **kwargs)
            finally:
                cls.unlock()
        return __deco
    return _deco

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding:gbk -*-
'''示例9: 装饰器带类参数,并分拆公共类到其他py文件中
同时演示了对一个函数应用多个装饰器'''
from mylocker import *
class example:
    @lockhelper(mylocker)
    def myfunc(self):
        print(" myfunc() called.")
    @lockhelper(mylocker)
    @lockhelper(lockerex)
    def myfunc2(self, a, b):
        print(" myfunc2() called.")
        return a + b
if __name__=="__main__":
    a = example()
    a.myfunc()
    print(a.myfunc())
    print(a.myfunc2(1, 2))
    print(a.myfunc2(3, 4))

下面是参考资料,当初有不少地方没看明白,真正练习后才明白些:

1. Python装饰器学习 http://blog.csdn.net/thy38/article/details/4471421

2. Python装饰器与面向切面编程 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

3. Python装饰器的理解 http://apps.hi.baidu.com/share/detail/17572338

转载于:https://www.cnblogs.com/chegnshi-coding/p/4457743.html

python中的函数修饰符相关推荐

  1. python中的函数修饰器

    python中的函数修饰器 – @wrapper 简介 类似于C#的属性.Java的注解,python也有对应的修饰符.从Python2.7和Python3开始,提供了以'@'为标示的修饰符,可以在模 ...

  2. python中函数修饰符_python中的函数修饰符

    首先,什么是函数修饰符?函数修饰符就是对原有函数做一层包装.比如有以下两个函数: def func1(): print 'I am function func1' def func2(): print ...

  3. Python中的@classmethod修饰符

    classmethod修饰符对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的cls参数,可以来调用类的属性,类的方法,实例化对象等 class A(object):bar = ...

  4. python修饰符作用_python函数修饰符@的使用

    python函数修饰符@的作用是为现有函数增加额外的功能,常用于插入日志.性能测试.事务处理等等. 创建函数修饰符的规则: (1)修饰符是一个函数 (2)修饰符取被修饰函数为参数 (3)修饰符返回一个 ...

  5. python类方法中使用:修饰符@staticmethod和@classmethod的作用与区别,还有装饰器@property的使用

    python类方法中使用:修饰符@staticmethod和@classmethod的作用与区别,还有装饰器@property的使用(3-20181205) 文章目录: 一. @staticmetho ...

  6. python修饰符号的使用_Python 函数修饰符(装饰器)的使用

    Python函数修饰符(装饰器)的使用 1.修饰符的来源 修饰符是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 修饰符是解决这类问题的绝佳设计,有了修 ...

  7. Python 字符串常见的语句,和练习题,字符串练习题 Python 切片函数修饰符 #精度和进制Python 字符串一些语句练课件练习题

    字符串练习题 Python 切片 函数修饰符 #精度和进制 Python 字符串一些语句练 课件练习题 4,.by     字符串的替换         方法    描述         replac ...

  8. Python学习笔记11:函数修饰符

    Python学习笔记11:函数修饰符 Python有很多有趣的特性,其中函数修饰符就是一个. 我们在之前的那个web应用示例中用过如下写法: @web.route('/log') @符号后边的,就是一 ...

  9. 从Python中readline()函数读取的一行内容中去掉换行符\n

    从Python中readline()函数读取的一行内容中含有换行符\n,很多时候我们需要处理不含有换行符的字符串,此时就要去掉换行符\n. 方法是使用strip()函数. 例子如下: file = o ...

最新文章

  1. Zabbix-3.0.3实现微信(WeChat)告警
  2. mac下载安装本地mongodb
  3. xgboost与gbdt的区别
  4. Android自动化测试 - 自动化测试工具比较
  5. python 调用mysql_Python中直接在MySQL执行SQL命令
  6. 每日总结-2016年3月9日
  7. Redis的内存淘汰策略问题
  8. Exynos4412启动过程分析
  9. Android系统(142)动画---动画使用攻略
  10. 基于Vue3在线商城(Vue3+VueCLI+VueRouter+vuex+axios+Bootstrap)
  11. 壳聚糖导管复合辛伐他汀/泊洛沙姆407水凝胶/负载转化生长因子β1温敏性壳聚糖水凝胶的制备
  12. ARCGIS水文分析:水库容量和蓄水区计算
  13. 【并发】Amdahl's Law 阿姆达尔定律
  14. to_date的用法
  15. DHCP 和 DHCP-Realy 功能演示完整示例
  16. stm32+定时器PWM波+电机驱动+直流电机
  17. java guice_如何在Guice中进行需要注入实例的动态绑定?
  18. 计算机控制点火系统如何控制点火提前角,电子点火系统如何控制点火提前角?...
  19. 【物联网】第2章 自动识别技术与RFID
  20. 百度地图绘制途径点/分段绘制路线

热门文章

  1. idea下的application.properties下写汉字乱码问题
  2. db2分页查询sql语句_MySQL学习(八):SQL查询语句的用法和优化
  3. JVM插桩之四:Java动态代理机制的对比(JDK和CGLIB,Javassist,ASM)
  4. Python3快速入门----(3) dict(字典结构)
  5. 《剑指offer》数值的整数次方
  6. 【搜索引擎Jediael开发笔记1】搜索引擎初步介绍及网络爬虫
  7. pandas全表查询定位某个值所在行列
  8. dojo中的dojo/dom-style
  9. 初学者也能看懂的DPDK解析
  10. Elasticsearch SQL介绍及实例