装饰器

# coding:utf-8


import time

# 装饰器:主要是实现在不修改原有函数功能的基础上,添加额外的一些功能。而装饰器的实现
就是利用闭包这种语法结构完成的。一般应用于代码的日志输出,程序的性能测试。

# [(<frame object at 0x00000000023AF8E0>, 'C:/Users/Administrator/
Desktop/PythonSix/12-25/am/\xd7\xb0\xca\xce\xc6\xf7.py', 8, 'debug', 
['    fun_name = inspect.stack()\n'], 0), (<frame object at 
0x0000000001D46528>, 'C:/Users/Administrator/Desktop/PythonSix/12-25
/am/\xd7\xb0\xca\xce\xc6\xf7.py', 12, 'show1', ['    debug()\n'], 0),
 (<frame object at 0x0000000001D461E8>, 'C:/Users/Administrator/Desktop
/PythonSix/12-25/am/\xd7\xb0\xca\xce\xc6\xf7.py', 19, '<module>', 
['show1()\n'], 0)]
# def debug():
#     import inspect
#     fun_name = inspect.stack()[1][3]
#     print "[DEBUG]:execute function named {}()".format(fun_name)
#
# def show1():
#     debug()
#     print 'show1()函数执行了'
#
# def show2():
#     debug()
#     print 'show2()函数执行了'
#
# show1()
# show2()

# 如何设计一个装饰器
# 当调用一个函数时,通过装饰器实现打印一个函数的执行时间及当前函数的函数名。
# fun_name形参是用于接收要检测的函数名
# def DEBUG(fun_name):
#     print 'fun_name = ',fun_name.__name__
#     def wrapper():
#         # 起始时间戳
#         start_time = time.time()
#         fun_name() # 就是在调用custom_fun函数
#         # 终止时间戳
#         end_time = time.time()
#         # 时间差
#         second = end_time - start_time
#         print '[DEBUG]: function execute time is {}s'.format(second)
#     return wrapper


# def custom_fun():
#     # sleep()让一段代码的执行,休眠一段时间之后再执行后续逻辑。
#     time.sleep(2)
#     print('------')
#
# wrapper_fun = DEBUG(custom_fun)
# print '-----------------wrapper_fun接收的函数名:',wrapper_fun.__name__
# wrapper_fun()

# 通过‘@’语法糖模式,设置装饰器

# @DEBUG
# def custom_fun():
#     print 'custom_fun()开始执行了'
#     time.sleep(2)
#     print 'custom_fun()执行结束了'
# custom_fun()
#
# @DEBUG
# def fun():
#     time.sleep(3)
# fun()


def show_function_name(function_name):
    def wrapper(args):
        function_name(args)
        print("[DEBUG]:{}() function is executed".format
(function_name.__name__))
    return wrapper

# @show_function_name
# def show():
#     print('0000000000000000')
# show()
# res_function = show_function_name(show)
# res_function()

@show_function_name
def show1(string):
    print('show1 -------- %s'%string)
# 需要在装饰器内部接收实参 '吃饭了',等到装饰器内部执行show1()函数调用的时候,
会将实参再赋值给string这个形参。
show1('吃饭了')

# 装饰器的执行过程:
# 1>执行@show_function_name这个装饰器,由于装饰的是show1()函数,所以将show1
函数名传递到闭包函数show_function_name中的形参,同时将内嵌函数wrapper进行返回。
# 2>执行show1('吃饭了'),实际上是在执行wrapper()函数,此时继续到内嵌函数wrapper()
中执行代码逻辑,其中就包含show1函数的调用。

# 对装饰器进行扩展,提高不同类型函数的适用性。
def debug_fun(fun):
    def wrapper(*args, **kwargs):
        print('[debug]: {}() 函数执行了'.format(fun.__name__))
        fun(*args, **kwargs)
    return wrapper

@debug_fun
def work():
    print('==============')
work()

@debug_fun
def eat(name):
    print('今天吃了{}。'.format(name))
eat('米饭')

@debug_fun
def study(time, content):
    print('今天学习了{1},时间是{0}小时。'.format(time,content))
study('8', 'Python')


# 通过装饰器,实现类和对象模式下的单例功能。

# 面向对象中的继承:子类和父类之间的耦合性更强,一旦父类功能失效,那么子类功能也将无法
使用。
# 装饰器中,函数原有功能和函数的扩展功能之间的耦合性较弱。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值