1. 程式人生 > >函式物件,名稱空間和作用域以及閉包函式和裝飾器

函式物件,名稱空間和作用域以及閉包函式和裝飾器

重點:函式func() 兩層含義:

  第一層: func 指函式物件,指向記憶體地址

  第二層: 括號表示觸發函式功能

一. 函式物件(可以理解為函式名):在面對物件中,一切皆物件

  具體體現:1.函式可以引用

       2.可以作為函式的引數

       3.可以作為函式返回值

          4.可以被儲藏在容器中

二. 函式巢狀: 在一個函式中呼叫了另一個函式

  巢狀:在一個函式中定義了另一個函式,定義在內部的函式只能在函式內部使用。

三.  名稱空間:儲存名字和記憶體地址關係的空間

  分類:1. 內建名稱空間: 儲存直譯器自帶的一些名稱與值的對應關係(print,  len, max, min,pop 等)

               在直譯器啟動時建立

     2. 全域性名稱空間:檔案級別的名稱(除了內建和函式內的都為全域性)

             在執行py 檔案時建立,所有檔案程式碼執行完畢結束

       3. 區域性名稱變數:在內部函式內的名稱。

             呼叫函式時建立,函式執行完銷燬

  比較: 載入順序: 內建變數 ===> 全域性變數====> 區域性變數

      查詢順序: 區域性變數===> 全域性變數 ====> 內建變數

四. 作用域: 域指範圍: 函式的作用域在定義時就固定了,與呼叫為止無關

      全域性名稱空間和內建的名稱空間在使用上沒有什麼本質區別, 而區域性名稱只能區域性使用

      global: 定義全域性變數,其變數可以在全域性範圍內使用

      local: 區域性作用域

      globals(): 以字典型別返回當前位置的全部全域性變數

      dir() : 不帶引數時返回當前範圍內的變數,方法和定義的型別列表,帶引數時,返回引數的屬性方法列表。 ???

      locals() : 檢視區域性作用域中的內容(相對概念)

      global a:明確要使用全域性中的變數 a

      nonlocal a: 使用上一層中的a, 如果上一層沒有就在上上層找,找到為止,但不表示使用全域性變數

四. 閉包函式:滿足兩個條件

  條件一: 定義在另一個函式中

  條件二: 在內部的函式中使用了外部的名稱(也就是資料值)

  重點: 在返回內部函式時,不是單純的返回函式,還把函式中訪問到的區域性名稱一起打包了

      相當於將內部函式與訪問的資料打包在一起了

      __closure__用於訪問閉包時打包的資料 print(f.__closure__[0].cell_contents)

      如果為全域性變數沒必要包走,外部可直接訪問

def fun1():
    name='iris'
    def inner():
        print(name)
        print('hello')
    return inner
f=fun1()  # f 就是inner
f()  

五. 裝飾器:在不修改原始碼和呼叫方式的條件下為其他函式增加功能的函式

  特點:開閉原則(對擴充套件開放,對修改封閉)

     裝飾器通過閉包函式實現

#原始碼:
def download():
    print('開始下載')
    time.sleep(2)
    print('下載結束')
download()
# 為原始碼加上統計開始時間和結束時間並計算總耗時的功能
# 方法一:修改原始碼方法
import time
def download():
    start_time=time.time()
    print('開始下載')
    time.sleep(2)
    print('下載結束')
    end_time=time.time()
    print('下載耗時',(end_time-start_time))
download()

# 方法二:修改呼叫方式
import time
def download2():
    start_time=time.time()
    download()
    end_time = time.time()
    print('下載耗時',(end_time-start_time))
download2()

# 方法三:裝飾器
def download():
    print('開始下載')
    time.sleep(2)
    print('下載結束')

def outter(func):
    def inner():
        start_time=time.time()
        func()
        end_time=time.time()
        print('下載耗時', (end_time-start_time))
    return inner
import time
download=outter(download)
download()

六. 時間戳: time.time()

  用秒錶示當時的時間,指從1970年一月一日零點零分到現在經過的秒數。