1. 程式人生 > >零基礎入門Python3-函數式編程(4)

零基礎入門Python3-函數式編程(4)

partial code area 數值 aaa decorator 零基礎 基礎 inner

一、裝飾器(decorator)

當我們定義好一個函數的時候,還想為函數添加一些功能,但是不想改變已經函數。這個時候,我們就可以使用裝飾器,為定義好的函數添加功能,且不修改函數中的代碼,是非常好用的一個方法。這裏要註意一下,所謂的添加功能,指的是在函數執行前或執行完後添加功能。

# 實例1,定義一個函數,輸入字符串"python"

def func():

print(‘python‘)

func()

>>> python

如果我們想在字符串 "python" 前面添加另外一個字符串 "hello"

# 實例2

def add(func):

print(func.__name__)

# xxx.__name__ 代表的是取函數名稱,這裏是取func1的函數名稱

def f():

print("hello")

# 在func1函數運行前,打印出 "hello"

func()

# 運行 func1,這裏已經把 fun1賦值給變量func了

return f

# 這裏是一個返回函數

@add

# 在定義函數的前一行使用python的 @ 符號,等於執行了 func1 = add(func1)

def func1():

print(‘python‘)

func1()

print(func1.__name__)

# 再一次輸出 func1 的函數名稱

>>> func1

hello

python

f

# 因為函數 f 作為返回函數,func1 在函數 f 中執行,所以 func1 函數賦給了 函數 f,所以,函數的名稱會發生變化。

我們看看裝飾器的局限性

# 實例3

def add(func):

def f1():

print(‘+ add qian mian‘)

func()

print(‘+ add hou mian‘)

return f1

@add

def f2():

print(‘zhe shi han shu de gong neng‘)

f2()

>>> + add qian mian

zhe shi han shu de gong neng

+ add hou mian

# 這個實例說明了,我們只能往函數執行前或者執行後的地方添加功能。

當我們想往附加的函數中傳入參數的時候,必須另外嵌套一個函數,以此傳入參數。

# 實例4

def addtext(text1,text2):

def add(func):

def f1():

print(‘+ add {0}‘.format(text1))

func()

print(‘+ add {0}‘.format(text2))

return f1

return add

@addtext(‘aaaa‘,‘bbbb‘)

def f2():

print(‘zhe shi han shu de gong neng‘)

f2()

>>> + add aaaa

zhe shi han shu de gong neng

+ add bbbb

# 當我們要傳入參數值的時候,在 @函數名的後面附加一個圓括號,並帶入參數。@addtext(‘aaaa‘,‘bbbb‘) 等同於 f2=addtext(‘aaaa‘,‘bbbb‘)(f2)

# f2=addtext(‘aaaa‘,‘bbbb‘)(f2) ,首先執行的是 addtext(‘aaaa‘,‘bbbb‘),然後執行 add(f2)......

我們在實例3中出現一個函數名稱會變化的問題,我們該怎麽解決呢?使用 functools.wraps

# 實例5

import functools

# 導入functools模塊

def add(func):

print(func.__name__)

@functools.wraps(func)

def f():

print(‘addtext‘)

func()

return f

# 開始定義函數 f1

@add

def f1():

print(‘python‘)

f1()

print(f1.__name__)

# 首先導入functools函數,利用@functools.wraps(func) 來解決函數名變化的問題。切記不要使用 f.__name__=func.__name__

二、偏函數

當我們要經常使用 int 進行二進制轉換為十進制的時候,會用到 print(int(‘100011‘,2)) 。但是如果每次進行轉換的時候,都要對 int 的參數base賦值,這樣是很麻煩。那怎麽解決呢?

# 實例1

def _int(n,base=2):

return (n,base)

_int(1010101)

>>> 35

# 這是一種解決辦法,重新定義一個函數。

但是,python 的模塊 functools.partial 可以幫我們創建一個偏函數,省去了自定義函數的麻煩

functools.partial(函數名稱,參數)

- 作用就是相當於把參數給固定了,不用每次都給賦值

# 實例2

import functools

_int=functools.partial(int,base=2)

print(_int(‘101011‘))

>>> 43

偏函數可以傳入函數對象、*args和**kw這3個參數

# 實例3

import functools

s=functools.partial(max,1123)

print(s(666,22))

>>> 1123

# functools.partial(max,1123)中,1123 以參數的形式傳入max函數中,並進行運算。

# 實例4

import functools

k={‘base‘:2}

_int=functools.partial(int,**k)

print(_int(‘10101‘))

# functools.partial 接收了 **kw 參數

技術分享圖片 關註公眾號,了解更多!

零基礎入門Python3-函數式編程(4)