欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

函数(三)

程序员文章站 2022-07-10 23:43:06
闭包函数 定义:函数内部函数对外部作用域而非全局作用域的引用 两张函数参数的方式 使用参数 包给参数 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。 装饰器 装饰器指:未被装饰器对象添加额外的功能。 注意: ......

闭包函数

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

两张函数参数的方式

  • 使用参数

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

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