经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Ruby » 查看文章
2019-07-11 闭包函数和装饰器
来源:cnblogs  作者:看好你哦  时间:2019/7/15 9:00:26  对本文有异议

一、闭包函数

  定义:定义在内部的函数引用外部函数的名字(变量)叫做闭包函数

  要打印的是inner函数的x,因为这个函数里面没有定义x的值,所以找上一层的局部变量x = 111。执行代码,outter函数被调用,返回值为inner,用变量res接收,所以res = inner,下面再用res(),就是inner(),调用inner函数,执行里面代码,打印结果为111

  1. def outter():
  2. x = 111
  3. def inner():
  4. print(x)
  5. return inner
  6. res = outter() # res就是inner函数内存地址
  7. res() #111

  给函数体传值的两种方式:

    1.函数调用时候直接传参

  1. def index1(username):
  2. print(username)
  3. res = index1('aa') #aa

    2.闭包传参

  这个和刚开始定义的闭包函数一样只不过是把变量x,y放在outter函数里面当形参,在调用的时候传实参

  1. def outter(x,y):
  2. # x = 1
  3. # y = 40
  4. def my_max():
  5. if x > y:
  6. return x
  7. return y
  8. return my_max
  9. res1 = outter(1,40) # res就是my_max函数的内存地址
  10. print(res1()) #40

 

二、装饰器

  定义:给被装饰的对象添加新的功能的一个工具。  目的:更方便的使用新添加的新功能

  装饰器(可调用对象)必须遵守的两个原则:

    1.不可改变被装饰对象的代码

    2.不可改变 被装饰对象的调用方式(假如调用方式是idnex(),使用装饰器之后也是这种调用方式)

  

  简单版本:

  在原始函数index函数上加一个时间计算功能,最后也是调用了index(),没有违反装饰器的两个原则。运行函数先到outter调用,里面传一个参数index(这个是最原始的index函数的内存地址),然后返回get_time,用变量index接收。index()其实就是调用get_time函数。执行里面代码,func()就是之前传的func参数,index()调用。

  1. import time
  2. def index():
  3. time.sleep(3)
  4. print('睡醒了')
  5. def outter(func): # func = 最原始的index函数的内存地址
  6. def get_time():
  7. start = time.time()
  8. func() # func = index函数的内存地址() 直接调用
  9. end = time.time()
  10. print('index run time:%s'%(end-start))
  11. return get_time
  12. index = outter(index) # outter(最原始的index函数内存地址)
  13. # index指向get_time函数的内存地址
  14. index() #睡醒了

  升级版本:(被装饰的函数需要参数,之前的用法需要在get_time里面的func()写参数,才能使用正确。统一参数写法:*args,**kwargs)

  1. import time
  2. def index():
  3. time.sleep(3)
  4. print('澳门最大线上赌场开业啦 性感tank在线发牌!')
  5. return 'index'
  6. # res1 = index()
  7.  
  8. def login(name):
  9. time.sleep(1)
  10. print('%s is sb'%name)
  11. return 'login'
  12. # res = login('egon')
  13.  
  14. def outter(func): # func = 最原始的login函数的内存地址
  15. def get_time(*args, **kwargs): # args = ('egon',) kwargs = {}
  16. start = time.time()
  17. res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon')
  18. end = time.time()
  19. print('func run time:%s'%(end-start))
  20. return res
  21. return get_time
  22. login = outter(login) # outter(最原始的login函数的内存地址)
  23. res = login('egon')
  24. print(res)
  25. index = outter(index)
  26. res1 = index()
  27. print(res1)
代码

  这样设置之后可以接受任意参数的函数。

 三、装饰器语法糖

  语法糖在书写的时候应该与被装饰器紧紧挨着,两者之间不要有空。把装饰器赋值给紧挨这的的可调用对象,并且把紧挨着的函数名当做参数传递到装饰器中

 

四、多个装饰器一起使用

   注意:装饰器装饰顺序:从下往上

        装饰器执行效率:从上往下

 

 

 

原文链接:http://www.cnblogs.com/wangcuican/p/11172978.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号