1. 程式人生 > >Python學習(九)--[進階]函數

Python學習(九)--[進階]函數

相同 pen 調用 UNC 返回函數 列表 日誌 ref str

  • 閉包
Python的函數時可以嵌套的,可以將一個函數放在另外一個裏面。
def multiplier(factor):
    def multiplyByFactor(number):
        return number*factor
    return multiplyByFactor
調用multiplier()時,返回的是裏層函數,也就是說函數本身被返回了,但並沒有被調用。重要的是返回的函數還可以訪問它的定義所在的作用域。 在一個外函數中定義了一個內函數,內函數運用了外函數的臨時變量,並且外函數的返回值是內函數的引用,這樣就構成了一個閉包。如果外函數在結束的時候發現自己的臨時變量將來會在內函數中用到,就會把這個臨時變量綁定給了內部函數,然後自己再結束。 使用閉包的過程中,一旦外函數被調用了一次返回內函數的引用,雖然每次調用內函數是開啟一個函數執行過後消亡,但是閉包變量實際上只有一份,每次開啟內函數都在使用同一份閉包變量。 可以來看一個例子:
def
count(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fs f1, f2, f3 = count()
在這個例子裏,每次循環,都會創建一個新的函數,然後把函數名放到列表fs裏,並沒有調用函數f,也就是說不會進行內部計算。最後把三個函數都返回。這裏要註意的是,外函數變量fs,i都是只有一份的,所以循環了3次以後,i就變成了3。所以最後我們發現調用f1(),f2(),f3()返回的結果都是9。
>>> f1()
9 >>> f2() 9 >>> f3() 9
  • 匿名函數
lambda作為表達式,定義了一個匿名函數。比如:lambda x: x+1。實際上是定義了一個函數,和下面的效果一樣。
    def fun(x)
        return(x+1)
  • 裝飾器
在Python裏函數也是一個對象,函數對象有一個__name__屬性,可以拿到函數的名字:
>>> def name():
...     print Tom
...
>>> name.__name__
‘name
如果想要增強name()函數的功能,但是又不希望修改name()函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”。 裝飾器就是一個返回函數的高階函數,比如定義一個打印日誌的裝飾器:
def log(func):
    def wrapper(*args, **kw):
        print call %s(): % func.__name__
        return func(*args, **kw)
    return wrapper
log是一個裝飾器,接受一個函數作為參數,並返回一個函數。所以我們使用裝飾器時,就需要用@語法:
@log
def name():
    print ‘Tom
多以現在調用name(),相當於執行了name = log(name),然後再執行name()。
  • 偏函數
Python的functools模塊提供了片函數的功能。 比如int()函數可以把字符串轉換為整數,也可以傳入base參數,設置轉換的進制。比如int(‘1234’,base = 8)。如果要轉換大量的八進制字符串,每次都要傳入進制參數,於是可以:
def int8(x,base = 8)
    return int(x,base)
我們也可以使用片函數實現相同的效果,也就是:
int8 = functools.partial(int, base=2)

參考文章:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000

Python學習(九)--[進階]函數