zoukankan      html  css  js  c++  java
  • day13

    函数的嵌套定义

    #在函数内部定义另一个函数
    #为什么要有函数的嵌套定义:
    # 1)函数fn2想直接使用fn1函数的局部变量,可以讲fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量
    # 2)函数fn2名字就变成fn1的局部变量了,正常只能在fn1中使用,想在外部使用,可以讲fn2函数对象作为fn1函数的返回值
    # 3)在外部也用同名的变量fn2来接收fn1函数的执行结果(fn1函数的返回值),那么fn2也就是可以在外部被调用

    global nonlocal关键字

    '''
    global:将局部的变量作用域提升为全局变量
    当全局已经拥有一个变量,在函数内部定义一个有global修饰的变量,那么这两个就是一个变量
    想要在函数定义一个全局变量,全局要没有同名的变量
    +=也属于改变自身的范畴,当在外面有全局变量,函数内部要对该变量自身进行运算,必须使用global修饰

    nonlocal:
    将变量提升为嵌套作用域(有两个函数,内部函数的内部变量的作用域提升为外层函数的变量作用域),外部函数必须已存在一个同名变量
    如果局部想改变嵌套局部变量的值(发生地址的变化),可以用nonlocal声明该变量
    +=,-=,等对自身的运算也算对自身改变,也要用nonlocal
    '''

    闭包及闭包的运用场景

    '''
    闭包:被函数包裹的函数,也可以理解为函数内部的函数
    闭包的应用场景:
    闭包中使用的变量可以被外层函数所传递 -- 外层函数可以为闭包传递参数
    延迟执行
    开放封闭原则:在不修改源代码和调用方式的情况下给函数添加新功能

    '''

    装饰器

    '''
    满足开放封闭原则的闭包应用
    @outer语法来调用outer,规定传入被装饰的函数对象,所以参数固定为一个,接收被装饰的函数对象

    def outer(func):  
      不能确定被装饰的函数的参数:来者不拒,用可边长来接受
      def inner(*args, **kwargs):
          pass # 新功能位
          res = func(*args, **kwargs) # 解压带给原功能
          pass # 新功能位
          return res
      return inner
      使用装饰器(outer),得到新功能(inner)
       

    用被装饰的函数名去接受装饰器的执行结果,调用装饰器时传入被装饰的函数对象
    @outer # fn = outer(fn) = inner
    def fn(): pass
    '''

    一个函数被多次装饰

    '''
    def outer(func):
      def inner(*args, **kwargs):
          res = func(*args, **kwargs)
          return res
      return inner


    def check_user(func):
      def inner(*args, **kwargs):
          # 账号的验证功能
          user = args[0] # type: str
          if not (user.isalpha() and len(user) >= 3):
              print('账号不合法')
              return False

          res = func(*args, **kwargs)
          return res
      return inner

    def check_pwd(func):
      def inner(*args, **kwargs):
          pwd = args[1]
          if len(pwd) < 3:
              print('密码不合法')
              return False

          res = func(*args, **kwargs)
          return res
      return inner

    def format_return(func):
      def inner(*args, **kwargs):
          res = func(*args, **kwargs)
          if res:
              return '登录成功'
          return '登录失败'
      return inner


    # 登录的原功能

    @format_return
    @check_user
    @check_pwd
    def login(user, pwd):
      if user == 'owen' and pwd == '123':
          return True
      return False

    user = input('user: ')
    pwd = input('pwd: ')
    res = login(user, pwd)
    print(res)

    # 执行过程:调用login => 进入第一个装饰器(format_return)的inner => 进入第二个装饰器(check_user)的inner => 进入第三个装饰器(check_pwd)的inner => 开始返回,从第三个返回到第二个再返回到第一个,最后返回到外界调用的位置

    '''
  • 相关阅读:
    错误 1324。文件夹路径 .. 中含有无效的字符
    linux下 tar解压 gz解压 bz2等各种解压文件使用方法
    取消EXCEL 2007/2010中邮箱地址的自动链接
    Windows2000/XP启动过程详解
    Ubuntu下安装apache2,mysql,php,wordpress.
    offcie2007,2010,2012中快速删除指定的页面.
    mysql连接,修改密码,增加用户,显示,导入导出
    键盘各按键的使用
    cvim 使用
    matlab基础知识(basic operation)
  • 原文地址:https://www.cnblogs.com/zhuqihui/p/10787143.html
Copyright © 2011-2022 走看看