1. 程式人生 > >day11 閉包函式和裝飾器

day11 閉包函式和裝飾器

1.函式不是新知識點 主要是學習函式的用法

在面向物件程式設計中,一切皆物件,函式也不例外

 

具體的表現

1.函式可以引用

2.函式可以作為函式的引數

3.函式可以作為函式的返回值

4.可以被儲存到容器型別中

 

def func1():

  pass

a=func() 

 

def func(func):

  func()

func2(func1)

 

def func3():

  return func1

 

def fun5():

  print('func5 run')

 

li2 = [func5]

li2[2]()

 

2.函式的巢狀

1.定義的巢狀,在一個函式的定義內再定義函式

def f1():

  print('f1')

  def f2():

    print('f2') 

  f2()

f1()

 

2.巢狀的呼叫,先定義好函式,在其他函式體內呼叫

def f1():

  print('f1')

def f2():

  print('f2')

  f1()

f2()

 

 

名稱空間就是一個字典,專門儲存名稱的空間,不僅儲存名字,還要知道記憶體地址

名稱空間分類

1.內建名稱空間,儲存直譯器的一些名稱與值的對應關係

(python 直譯器啟動時建立,所有程式碼全部執行完畢,關閉直譯器時銷燬)

2.全域性名稱空間  檔案級別的名稱,只要你的名字的定義是頂著最左邊寫的就是全域性空間

(執行py檔案時建立全域性名稱空間,所有檔案中的程式碼全部執行完畢,關閉直譯器時銷燬)

除了內建和函式內,都在全域性名稱空間中

3.區域性名稱空間:只要是在函式內的名稱都是區域性的

(呼叫函式時建立,函式執行完畢就銷燬)

 

名稱空間的載入順序

內建-》全域性-》區域性

 

名稱的查詢順序

區域性-》全域性-》內建的

3.作用域

域就是範圍的意思

全域性名稱空間和內建名稱空間,在使用上沒有區別

區域性的和全域性/內建的就有區別了:區域性定義的只能在區域性使用

 

給三個空間劃分範圍

全域性的內建的可以劃分為同一個範圍

global表示全域性範圍,就是所謂的全域性作用域

區域性的單獨劃分為一個範圍

local區域性作用域

 

檢視全域性作用域的內容globals()

檢視區域性作用域的內容 注意,你在全域性作用域使用locals看到的就是全域性的內容,域glaobals沒有區別

函式locals()

 

a = 'aasdasd'

 

print()

檢視全域性作用域中的內容

print(dir(globals()["__builtins__"]))

檢視區域性作用域中的內容 注意 你在全域性中使用locals 看到的就是全域性的內容,與globals沒有區別

 

關鍵字

global #宣告要使用全域性中的變數名

nonlocal #明確宣告 要使用上一層的a,如果上一層沒有,則找上上層,但是注意,不能找全域性中的

 

age=18

def func2():

  #明確宣告 要使用全域性中的age

  global age

  age = 19

  print(age)

fun2()

print(age) #因為區域性名稱空間中用了global,所以直接用的全域性變數age,直接被修改了

 

def f1():

  #age = 19

  def f2():

    nonlocal age #會報錯,因為往上層找沒有找到age

    print(age)

  f2()

f1()

print(age)

 

 

4.閉包函式

如下就是一個閉包函式

def fun1():

  age = 18

  def inner():

    print('hello')

    print(age)

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

  相當於將內部函式域訪問的資料打包在一起了 閉包這個名字就是這麼得來的

  return inner

f=fun1()

 函式的作用域在定義時就固定了,與呼叫的位置沒有關係

 

閉包函式的模版

def fun2():

  a = 1

  b=10

  def inner():

    print(a)

    print(b)

    print(c)

  return inner

 

f = fun2()

#__closure__用於訪問閉包函式 打包的資料

 

什麼是閉包函式

1.定義在另一個函式內的函式

2.內部的函式訪問了外部的名稱(資料) 注意 不包含全域性的

 

 

5.裝飾器

什麼是裝飾 給一個已有的物件(一個函式)新增新的功能

為什麼要裝飾:為了 增強功能

器:指一個工具,在python中,值得是具備某個功能的函式

簡單的說:裝飾器是一個用於其他函式增加功能的函式

 

開閉原則

指的是對擴充套件開放,對修改封閉(可以新增新功能,但不能修改原始碼和程式碼的呼叫方式)

使用者程式的使用者

用框架的使用者

print(time.time())返回一個時間戳,指的是1970年1月1日(unix元年)到現在一共經過的秒數

mac是Linux 核心,linux是unix的一個分支

 

裝飾器和閉包函式的關係:裝飾器是一種設計程式碼的套路(不修改原始碼和呼叫方式的情況下,增加功能)

要完成裝飾器就需要使用閉包函式

裝飾器不是閉包,閉包也不是裝飾器,只是通過閉包函式完成裝飾器的設計

把舊功能的函式傳進閉包函式,加好新功能,返回閉包函式,這樣在下次呼叫時,其實是在呼叫改版的舊函式

 

裝飾模式

 

def otter(func):

  def inner():

    在呼叫原始函式前,新增新功能  

    func()

  return inner

download = otter(download)

download()

 

既遵守了開閉原則,又添加了新功能