1. 程式人生 > >函數進階---作用域、閉包、裝飾器

函數進階---作用域、閉包、裝飾器

閉包 查看 就是 喜歡 name 應該 tro 變量 擴展

名稱空間

名稱空間指存放名字的地方
名稱空間分為三種

  • locals:函數內部的名稱空間,包括局部變量與形參
  • globals:全局變量,函數模塊定義所在模塊的空間
  • builtins 內置模塊的名稱空間
    不同變量的作用域不同就是由這個變量的所在變名空間決定的
    作用域:
    全局範圍:全局存活,在全局生效
    局部範圍:局部存活,在局部生效
    查看作用域的方法:locals(),globals()
    名稱空間的查找順序
    LEGB查找順序:locals-->enclosing function-->globals-->builtins
  • locals:指局部名稱空間
  • enclosing function:指外部嵌套函數的名稱空間
  • globals:全局變量,函數模塊定義所在的名稱空間
  • builtins:內置模塊的名稱空間

閉包

閉包是指內部函數包含對外部作用域而非全局作用域的引用,即:A函數裏再定義一個b函數(嵌套函數)而B函數裏調了A函數的變量,而A函數返回值是B函數的引用,這樣就構成了閉包

def fun():
    name = ‘ab‘
    def fun1():
        print(‘fun1‘,name)
    return fun1
a = fun()
a()

閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域

裝飾器

什麽是裝飾器?

裝飾器他人的器具,本身可以是任意可調用對象,被裝飾者也可以是任意可調用對象。
強調裝飾器的原則:

  • 不修改被裝飾對象的源代碼
  • 不修改被裝飾對象的調用方式
    裝飾器的目標:在遵循1和2的前提下,為被裝飾對象添加上新功能

程序員應該尊守封閉,開發原則!

  • 封閉:已實現的功能代碼塊不應該被修改
  • 開放:對現有功能的擴展開放

代碼:

flag = False

def login(fun):
    def ineer(*args,**kwargs):
        username = ‘alex‘
        password = ‘123‘
        global flag
        if flag == False:
            _username = input(‘user:‘).strip()
            _passwd = input(‘passwd:‘).strip()

            if _username == username and _passwd == password:
                print(‘登陸成功‘)
                flag = True
            else:
                print(‘登陸失敗‘)
        if flag == True:
            return fun(*args,**kwargs)
    return ineer

def home():
    print("---首頁----")

@login
def america():
    #login() #執行前加上驗證
    print(‘用戶已登陸,不需要驗證‘)
    print("----歐美專區----")

def japan():
    print("----日韓專區----")

@login #想當於henan = login(henan)
def henan(style):
    ‘‘‘
    :param style: 喜歡看什麽類型的,就傳進來
    :return:
    ‘‘‘
    #login() #執行前加上驗證
    print("----河南專區----")
henan(‘3p‘) #實際調用的是inner函數
america()

函數進階---作用域、閉包、裝飾器