漫天飞雪

函数(三)

闭包函数

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

两张函数参数的方式

  • 使用参数

    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')

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

posted @ 2019-05-31 20:03  1naonao  阅读(180)  评论(0编辑  收藏  举报