• 闭包函数与装饰器


    八.闭包函数:定义在函数内部的函数,并且该函数包含对外部函数作用中名字的引用,该函数就称为闭包函数
    闭:指的是定义在函数内部的函数
    作用域关系:在函数定义阶段就规定死了,与调用位置无关
    def outter():
    	x=2
    	def inner():
    		#x=1
    		print('from inner',x)
    
    	return inner
    f=outter()  #f=inner
    f()
    
    def foo():
    	x=111111111  #调用阶段赋不生效 函数体值在定义阶段生效
    	f()
    foo()
    
    应用场景:
    import requests
    import time
    def outter(url):
        #url='https://www.baidu.com'
        def get():
            response=requests.get(url)
            if response.status_code == 200:
                print(response.text)
        return get
    
    baidu=outter('https://www.baidu.com')
    time.sleep(3)
    
    baidu()
    
    
    九.无参装饰器
    装饰器即在不修改被装饰的对象源代码与调用方式的前提下,为装饰器对象的添加新功能
    装饰器与被装饰的对象均可以是任意可调用的对象
    装饰器==>函数
    被装饰的对象==>函数
    
    import time
    def index():
    	time.sleep(3)
    	print('welcome to index page')
    
    def home(name):
    	time.sleep(5)
    	print('welcome %s to home page' %name)
    
    def outter(func): #func=最原始的index   outter函数就是装饰器
    	def wrapper():  #func=index
    		start_time=time.time()
    		func()  #func()=index()
    		stop_time = time.time()
    		print('run time is %s' %(stop_time - start_time))
    	return wrapper
    
    
    index=outter(index)  #新的index=wrapper
    index()
    
    有无参装饰器之返回值
    import time
    def index(): #无参
    	time.sleep(3)
    	print('welcome to index page')
    	return 123456789
    
    def home(name):  #有参
    	time.sleep(5)
    	print('welcome %s to home page'%name)
    
    #####################装饰器##############
    def timmer(func):
    	def wrapper(*args,**kwargs):  #有参无参 都可以传值
    		start_time = time.time()
    		res=func(*args,**kwargs)  #最原始的index()
    		stop_time = time.time()
            print('run time is %s'(stop_time - start_time))
            return res  #返回最原始的index()的返回值
        return wrapper
    
    index=timmer(index)
    home=timmer(home)
    
    index()
    home('zhang')
    
    
    装饰器的语法:
    import time
    def outer(func):  
    	def inner(*args,**kwargs): #装饰器的参数
    		start_time = time.time()
    		res=func(*args,**kwargs)  #被装饰的函数
    		stop_time = time.time()
    		 print('run time is %s'(stop_time - start_time))
    		return res
    	return inner
    @outer	#index=outer(index)
    def index():
    	time.sleep(3)
    	print('welcome to index page')
    	return 123456789
    
    @outer  #home=outer(home)
    def home(home)
    	time.sleep(5)
    	print('welcome %s to home page'%name)
    
    index()
    home('zhang')
    
    #认证装饰器案例:
    import time
    current_user={
    	'username':None,
    }
    def auth(func):
    	def wrapper(*args,**kwargs):
    		if current_user['username']:  #None的布尔值一定为假 如果里面有值就一定为真
    			print('已经登录过')
    			res=func(*args,**kwargs)  #如果已经登录过 直接返回值给res 
    			return res
    
    		username=input('用户名>>>:').strip()
    		pwd=input('密码>>>:').strip()
    		if username == 'zhang' and pwd = '123':
    			print('登录成功')
    			res=func(*args,**kwargs)
    			return res
    		else:
    			print('用户或密码错误')
    	return wrapper
    
    @auth  #index=auth(index)
    def index():
    	time.sleep(1)
    	print('welcome to index page')
    	return 122
    @auth  #home=auth(home)
    def home(home):
    	time.sleep(2)
    	print('welcome %s to home page'%name)
    
    index()
    home('zhang')
    
    #叠加装饰器
    import time
    current_user={
        'username':None,
    }
    
    def auth(func):
        #func=index
        def wrapper(*args,**kwargs):
            if current_user['username']:  #None的布尔值为假 如果有值 一定为真
                print('已经登录过')
                res=func(*args,**kwargs)
                return res
    
            username=input("用户名>>:").strip()
            pwd=input("密码>>:").strip()
            if username == 'egon' and pwd == '123':
                print('登录成功')
                current_user['username']=username
                res=func(*args,**kwargs)
                return res
            else:
                print('用户名或密码错误')
        return wrapper
    
    def timmer(func):
        def wrapper(*args,**kwargs):   #以什么形式传参就以什么形式返回值
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print(stop_time-start_time)
            return res
        return wrapper
    
    @timmer  #统计的是auth+index的执行时间 跟装饰器的位置有关
    @auth  #index=auth(index)
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    index()
    
    有参装饰器:
    import time
    current_user={
        'username':None,
        # 'login_time':None
    }
    
    def auth(engine):
        # engine='file'
        def auth2(func):
            # func=index
            def wrapper(*args,**kwargs):
                if engine == 'file':
                    if current_user['username']:
                        print('已经登陆过了')
                        res=func(*args,**kwargs)
                        return res
    
                    uname=input('用户名>>: ').strip()
                    pwd=input('密码>>: ').strip()
                    if uname == 'zhang' and pwd == '123':
                        print('登陆成功')
                        current_user['username']=uname
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('用户名或密码错误')
                elif engine == 'mysql':
                    print('基于MyQL的认证')
                elif engine == 'ldap':
                    print('基于LDAP的认证')
            return wrapper
        return auth2
    
    @auth('file') #@auth2 #index=auth2(index) #index=wrapper  解释器遇到括号里面的先执行
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    
    index() # wrapper()
    

      

  • 相关阅读:
    thinkphp怎么修改配置进入默认首页
    apache中怎么配置网站的默认首页
    [转]数据库更新(Update语句)查询
    ACCESS删除datagridview和数据库中的一条数据,同时更新显示的方法源码
    想ACCESS数据库插入新的用户
    C# 对象不能从 DBNull 转换为其他类型。
    windows form参数传递过程
    向ACCESS数据库中的表导入EXCEL表,在 System.Data.OleDb.OleDbException 中第一次偶然出现的“System.Data.dll”类型的异常
    C#实现Access导入导出Excel
    dataGridView1.DataSource,解决查询结果不从第一行显示,而是不断往表下面扩展问题
  • 原文地址:https://www.cnblogs.com/zhangcaiwang1/p/9697582.html
Copyright © 2020-2023  润新知