Table of Contents
03總結
目的:在不修改函數內部的前提下修改函數功能
01 基本功能的實現方法
#問題:初中學過函數(y=kx+b, y=ax^2+bx+c)
#以y=kx+b爲例,計算一條線上多個點:給x得y
#法1 不能重用 k=1 b=2 y=k*x+b #法2同線多點時,k b不能保存 def line_2(k,b,x): print(k*x+b) line_2(1,2,0) |
#希望不會隨着函數的調用而結束 #法3 全局變量 換線需要每次對全局變量修改,代碼增多 k=1 b=2 def line_3(x): print(k*x+b)#使用全局變量不用加global,修改指向才需要 line_3(0) k=1 b=1 line_3(0) #法4 關鍵字參數配合缺省參數(缺省參數必須放最後) #優點:封裝,kb不可任意修改 #缺點:多線需要傳遞 def line_4(x,k=1,b=2): print(k*x+b) line_4(0) line_4(0,k=2,b=1) |
02使用類實現功能
只要創建完self實例,就隨着對象的存在而存在,而不會隨着方法的結束而結束
類中有__call__方法,則可對象後加括號觸發執行
#使用類(面向對象)可以保存重複使用的kb值 #法5:實例對象 缺點:每條線保存實例對象,使用空間較多 class Line5(object): def __init__(self,k,b): self.k=k#只要創建完self實例,就隨着對象的存在而存在,而不會隨着方法的結束而結束 self.b=b def __call__(self,x): print(self.k*x+self.b)
line_5_1=Line5(1,2) line_5_1(1) line_5_2=Line5(2,1) line_5_2(1) |
閉包:多層函數嵌套的定義,主要需要的是內部的函數,一般內部函數需要用到外部函數的變量
#法6 閉包(一個函數中套着另一個函數的定義,主要需要的是內部的函數,一般需要用到外部函數的變量) #核心需要的就是k、b、計算函數 def line_6(k,b):#帶着1,2調用函數 def create_y(x): print(k*x+b) return create_y#將函數指針返回
line_6_1=line_6(1,2)#調用函數,獲得計算y的函數的指針 line_6_1(1)#調用create_y,輸入形參x,b內部沒有定義,向外部找 |
閉包相對於面向對象,比較省空間,比較乾淨,只有所需的變量和方法的整體,沒有那麼多魔法屬性魔法方法
03
使用面向對象時的目的爲:全局變量可直接用,但暴露於其他函數
所以創立一個內存空間,其中有變量和函數
閉包也是有變量和函數,但沒有其他魔法屬性、方法
def line(k,b): num=100#也可擁有一個外部函數的變量 def create_y(x): print(k*x+b) return create_y |
將函數名作爲實參傳遞,得到引用,可以使用函數的代碼和變量
函數、匿名函數、閉包、對象區別:
函數將代碼封裝
匿名函數也可封裝代碼,但當作實參,完成小部分代碼時更方便
閉包不僅可給功能代碼,還可帶數據
實例對象的引用,可調用其中任何方法和屬性
04修改數據
修改外部函數變量的值,就像修改全局變量時加global一樣
x=3 def test1(): x=2 def test2(): print("x=%d" %x)#內部後面有定義,則外部不可用 x=1#定義了內部函數的局部變量 print("x=%d" %x)#1 return text2#不寫括號才返回引用,寫括號則得其返回值 t1=test() t1() |
def test1(): x=2 def test2(): nonlocal x#py3修改外部函數的局部變量 print("x=%d" %x) x=1#定義了內部函數的局部變量 print("x=%d" %x)#1 return text2#不寫括號才返回引用,寫括號則得其返回值 |
它閉包可以實現裝飾器