zoukankan      html  css  js  c++  java
  • 装饰器基本理论,高阶函数使用,函数闭包

    '''生成器只能遍历一次的另一个例子'''
    # def test():
    #    for i in range(5):
    #       yield i
    # t = test()
    # t1 = (i for i in t)
    # t2 = (x for x in t1)
    # print(list(t1)) # 此时t1是个生成器表达式,当利用list方法时,需要遍历生成器进行取值
    # print(list(t2)) # t2的值取之于t1,但是t1的值已经被list取完了,所以此时再取t1的值时已经取不到了
    
    
    '''
    一、什么是装饰器
    器即函数;装饰即修饰,意指为其它函数添加新功能;
    装饰器定义:本质就是函数,功能是为其它函数添加新功能
    二、装饰器需要遵循的原则
    1.不修改被装饰函数的源代码(开放封闭原则及)
    2.为被装饰函数添加新功能后,不修改被装饰函数的调用方式
    三、实现装饰器知识储备
    装饰器=高阶函数+函数嵌套+闭包
    '''
    
    # 开放封闭原则:程序一旦上线以后,不应该更改程序内部的源代码;因为一旦更改了程序的源代码,并不能知道会发生什么连锁反应,其它地方可能有调用
    import time
    
    # 新增需求:统计一个函数的运行时间,直接再函数内添加代码
    # def cal(l):
    #  start_time = time.time()
    #  res = 0
    #  for i in l:
    #     res += i
    #  stop_time = time.time()
    #  print('函数的运行时间是%s' % (stop_time-start_time))
    #  return res
    # print(cal(range(1000000)))
    
    # 利用装饰器的功能为其添加新需求
    # def timmer(func): # func指向的是cal()函数地址
    #  def wrapper(*args, **kwargs):
    #     start_time = time.time()
    #     res = func(*args, **kwargs)
    #     stop_time = time.time()
    #     print('函数运行时间是%s' % (stop_time-start_time))
    #     return res
    #  return wrapper # 返回函数名,方便指向此函数地址的cal使用cal()调用
    #
    # @timmer # cal = timmer(cal),此时cal指向的是wrapper函数地址
    # def cal(l):
    #  res = 0
    #  for i in l:
    #     res += i
    #  return res
    # print(cal(range(10000000)))
    
    
    '''
    高阶函数定义:
    1.函数接收的参数是一个函数名
    2.函数的返回值是一个函数名
    3.满足上述条件任意一个,都可称之为高阶函数
    '''
    
    # 高阶函数示范
    # def foo():
    #  print('我的函数名作为参数传给高阶函数')
    # def gao_jie1(func):
    #  print('我就是高阶函数1,我接收的参数名是%s' %func)
    #  func() # 函数接收的参数是一个函数名,没有返回值,只是执行了该函数
    # def gao_jie2(func):
    #  print('我就是高阶函数2,我的返回值是%s' %func)
    #  return func # 函数接收的参数是一个函数名,并且返回值是一个函数名
    # gao_jie1(foo)
    # gao_jie2(foo)
    
    # 高阶函数应用1:把函数当做参数传给高阶函数
    # def foo():
    #  print('from the foo')
    # def timmer(func):
    #  start_time = time.time()
    #  func()
    #  stop_time = time.time()
    #  print('函数%s 运行时间是%s' % (func, stop_time - start_time))
    # timmer(foo)
    # 总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
    
    # 高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
    # def foo():
    #  print('from the foo')
    # def timmer(func):
    #  start_time = time.time()
    #  return func  # 遇到return函数即停止了
    #  stop_time = time.time()
    #  print('函数%s 运行时间是%s' % (func, stop_time - start_time))
    # foo = timmer(foo)
    # foo()
    # 总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
    
    # 利用高阶函数的特点,做到了装饰器的原则,但是却运行了原函数两次
    # def foo():
    #  time.sleep(2)
    #  print('from the foo')
    # def timmer(func):
    #  start_time = time.time()
    #  func() # 第一次运行原函数
    #  stop_time = time.time()
    #  print('函数运行时间是 %s' % (stop_time - start_time))
    #  return func # 返回原函数的函数地址
    # foo = timmer(foo) # 利用和原函数名相同的变量进行接受函数地址
    # foo() # 第二次运行原函数
    
    # 函数嵌套:在函数内部定义另外一个函数
    # def father(name):
    #  print('from father %s' %name)
    #  def son(): # 函数即变量,所以这两个内部函数也算是局部变量
    #     print('from son')
    #     def grandson():
    #        print('from grandson')
    #     grandson() # 要运行内部函数,需要和函数所在位置为同一级;如果grandson()这个函数执行和son()函数同一级,那么会报错(NameError)
    #  son()
    # father('林海峰')
    
    # 闭包:在一个作用域里放入定义变量,相当于打了一个包
    # def father(name):
    #  def son():
    #     # name='alex'
    #     print('我朋友是 [%s]' %name)
    #     def grandson():
    #        # name='wupeiqi'
    #        print('我好哥们是 [%s]' %name)
    #     grandson()
    #  son()
    # father('林海峰')
    while True: print('studying...')
  • 相关阅读:
    关于java中的继承
    jdk?jre?
    spring AOP的两种配置
    ng-repeat如何限制循环次数
    AngularJS filter:search 是如何匹配的 ng-repeat filter:search ,filter:{$:search},只取repeat的item的value 不含label
    Anjular的ng-repeat
    SpringBoot扫描不到类,注入失败A component required a bean of type 'XXService' that could...
    React路由安装使用和多种方式传参
    Vue详细介绍模板语法和过滤器的使用!
    Vue定义组件和生命周期函数及实例演示!
  • 原文地址:https://www.cnblogs.com/xuewei95/p/14472027.html
Copyright © 2011-2022 走看看