函數(三)

閉包函數

定義:函數內部函數對外部做用域而非全局做用域的引用閉包

兩張函數參數的方式

  • 使用參數app

    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

裝飾器

裝飾器指:未被裝飾器對象添加額外的功能。url

注意:1,裝飾器自己實際上是能夠任意可調用的對象code

​ 2,被裝飾的對象能夠是任意可調用的對象對象

爲何須要裝飾器ip

​ 若是咱們已經上線了一個項目,咱們須要修改某一個方法,可是咱們不想修改方法的使用方法,這個時候能夠使用裝飾器。由於軟件的維護應該遵循開放封閉原則,即軟件一旦上線運行後,軟件的維護對修改源代碼是封閉的,對擴展功能指的是開放的。作用域

注意:1,不修改被裝飾對象的源代碼get

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

注意:裝飾器給函數增長功能嗎,可是不改變函數內部的語法,不改變函數調用方式

相關文章
相關標籤/搜索