函数(三)

2020-01-15 16:53:45 浏览数 (1)

闭包函数

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

两张函数参数的方式

  • 使用参数 def func(x) print(x) func(1) func(1) 1 1
    • 包给参数
代码语言:javascript复制
def outter(x)
    def inner()
        print(x)
    return inner
f = outter(1)
f()
代码语言:javascript复制
1

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

代码语言:javascript复制
import requests
def outter(url):
    def get():
        response = requests.get(url)
        print(f'done:{url}')
    return get
baidu=outter('https:www.baidu.com')
baidu()
代码语言:javascript复制
done: https://www.baidu.com

装饰器

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

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

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

为什么需要装饰器

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

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

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

怎么用装饰器

  • 传参方式:改变调用方式
  • 传参方式:包给函数——外包
代码语言:javascript复制
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}")
代码语言:javascript复制
welcome egon to home page
<function home at 0x102977620> time is -1.0005171298980713
res: egon
装饰器模板
代码语言:javascript复制
def deco(func):
  def wrapper(*args,**kwargs)
      res = func(*args,**kwargs)
      return res
  return wrapper
无参装饰器
代码语言:javascript复制
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()

有参装饰器

代码语言:javascript复制
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')

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

0 人点赞