zoukankan      html  css  js  c++  java
  • 函数(三)

    闭包函数

    定义:函数内部函数对外部作用域而非全局作用域的引用

    两张函数参数的方式

    • 使用参数

      def func(x)
      	print(x)
      func(1)
      func(1)
      
      1
      1
      
      • 包给参数
    def outter(x)
    	def inner()
    		print(x)
    	return inner
    f = outter(1)
    f()
    
    1
    

    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。

    import requests
    def outter(url):
    	def get():
    		response = requests.get(url)
    		print(f'done:{url}')
    	return get
    baidu=outter('https:www.baidu.com')
    baidu()
    	
    
    done: https://www.baidu.com
    

    装饰器

    装饰器指:未被装饰器对象添加额外的功能。

    注意:1,装饰器本身其实是可以任意可调用的对象

    ​ 2,被装饰的对象可以是任意可调用的对象

    为什么需要装饰器

    ​ 如果我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。

    注意:1,不修改被装饰对象的源代码

    ​ 2,不修改被装饰对象的调用方式

    怎么用装饰器

    • 传参方式:改变调用方式

    • 传参方式:包给函数——外包

      mport time
      
      
      def time_count(func):
          # func = 最原始的index
          def wrapper(*args, **kwargs):
              start = time.time()
              res = func(*args, **kwargs)
              end = time.time()
              print(f"{func} time is {start-end}")
      
              return res
          return wrapper
      
      
      @time_count  # home = time_count(home)
      def home(name):
          print(f"welcome {name} to home page")
          time.sleep(1)
      
          return name
      
      
      @time_count  # index = time_count(index)
      def index():
          print('welcome to index')
          time.sleep(1)
      
          return 123
      
      
      res = home('egon')
      print(f"res: {res}")
      
      welcome egon to home page
      <function home at 0x102977620> time is -1.0005171298980713
      res: egon
      

      装饰器模板

      def deco(func):
      	def wrapper(*args,**kwargs)
      		res = func(*args,**kwargs)
      		return res
      	return wrapper
      

      无参装饰器

      is_login_dict = {'username':None}
      def login_deco(func):
          def wrapper(*args,**kwargs):
              if not  is_login_dict['username']:
                  username = input('请输入你的用户名').strip()
                  if username != 'john':
                      print('非法输入')
                      return
                  is_login_dict['username']=username
                  res = func(*args,**kwargs)
                  return res
              else:
                  res = func(*args,**kwargs)
                  return res
          return wrapper
      
      @login_deco
      def withdraw():
          print('from withdraw')
      withdraw()
      withdraw()
      withdraw()
      

    有参装饰器

    is_login_dict = {'username': None}
    
    def auth(origin):
        
        def login_deco(func):
    
            def wrapper(*args, **kwargs):  # 赋值后的time_sleep
    
                if origin == 'file':
    
                    if not is_login_dict['username']:
    
                        username = input('请输入你的用户名》》》').strip()
    
                        if username != 'fanping':
                            print('非法登录')
    
                            return
    
                        is_login_dict['username'] = username
    
                        res = func(*args, **kwargs)  # 真正的time_sleep
    
                        return res
                    else:
                        res = func(*args, **kwargs)  # 真正的time_sleep
    
                        return res
    
                elif origin == 'mongodb':
                    print('非法登录')
                    
                else:
                    print('dsb')
    
    
            return wrapper
        
        return login_deco
    
    
    # f = origin('file')  # login_deco
    # shopping = f(shopping)
    # shopping()
    
    
    @auth('file')
    def shopping():
        print('from shopping')
    
    
    @auth('mongodb')
    def withdraw():
        print('from withdraw')
    

    注意:装饰器给函数增加功能吗,但是不改变函数内部的语法,不改变函数调用方式

  • 相关阅读:
    点击标签,通过jquery.jcarousel动态axaj加载内容,实现跑马灯效果
    FreeSwitch VoiceMail 语音信箱 研究
    FreeSwitch IVR VoiceMail 语音信箱
    微软企业库连接access,web.config相对路径配置
    FreeSWITCH 添加中文语音包
    FreeSwitch通过远程接口返回动态IVR语音菜单
    FreeSwitch注册上了,但拨打电话,提示Rejcted by acl "domians". Falling back to Digest auth
    ACM:密码截获
    c++ ACM:递归实例
    CSS:浏览器兼容性图表
  • 原文地址:https://www.cnblogs.com/1naonao/p/10957247.html
Copyright © 2011-2022 走看看