Python基礎之特殊的函式--裝飾器和偏函式

Roc Huang發表於2020-10-05

一、裝飾器

1.1 概述

在程式碼執行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)

裝飾器實際上就是一個閉包,把一個函式當做函式引數傳入,然後返回一個替代版函式,本質上就是一個返回函式的高階函式

1.2 簡單的裝飾器

函式也可以是一個物件,而且函式物件可以被賦值給變數,所以通過變數也可以呼叫該函式

def now():
	ptint("2018-3-18")
f = now
f()

函式物件有一個____name____屬性,可以拿到函式的名字:

def now():
    print("2018-4-3")

f = now
f()
print(now.__name__)
print(f.__name__)
#結果
'now'
'now'

現在我們要增強now()的函式功能,比如在函式呼叫前列印一段分隔符。

# 外函式
def log(func):
	# 內函式
	def wrapper():
		print("**********")
		return func()
	return wrapper

def now():
	print("2018-3-18")
	
#裝飾器的呼叫
f = log(now)
f()
1.3 複雜一點的裝飾器

需求:輸入年齡,並列印出來

def getAge(age):
	print("Tom age is %d"%age)
getAge(10)

#呼叫getAge方法得到年齡,但是如果輸入的是負數就會得到不符合常理的結果
getAge(-10)

def wrapper(func):
	def inner(num):
		if num < 0:
			num = 0
		return func(num)
	return inner
newGetAge = wrapper(getAge)
newGetAge(-10)

通過這樣的方式,我們的程式碼變得更加簡潔,將邊界檢查的邏輯隔離到單獨的方法中,然後通過裝飾器包裝的方式應用到我們需要進行檢查的地方。

另外一種方式通過在計算方法的開始處和返回值之前呼叫邊界檢查的方法能夠達到同樣的目的,但是不可置否的是,使用裝飾器能夠讓我們以最少的程式碼量達到座標邊界檢查的目的。

1.4 裝飾器@識別符號

使用@識別符號將裝飾器應用到函式

python2.4及以上版本支援使用識別符號@將裝飾器應用在函式上,只需要的函式的定義之前上@和裝飾器的名稱

def logger(func):
	def inner(*args,**kwargs):
		print("***********")
		return func(*args, **kwargs)
	return inner

@logger
def myPrint():
	print("you are very good")

myPrint()

說明:比如在公司實際開發的過程中,如果有一個別人寫好的函式,你想向其中新增某些功能或者修改某些功能,而人家要求你不能隨意修改人家的函式,則這時就可採用裝飾器,在不修改別人的原始碼的同時,還可以增加自己的功能。

二、偏函式

python中的functools模組提供了很多有用的功能,其中一個就是偏函式(Partial function)。

簡單來講偏函式的作用就是把函式的某些引數給固定住(也就是設定預設值),返回一個新的函式,呼叫這個新的函式會更簡單。

#functools 模組
import functools
#int()函式將字串轉換為整數,預設按十進位制轉換
#可以設定進位制
print(int("100",base = 2))
#結果為4,100是二進位制中4的表示

#類似於偏函式的功能
def int2(str, base=2):
	return int(str, base)
print(int2("10"))

#functools.partial可以幫助建立偏函式,不用自己定義int2函式
#作用:把一個函式的某些引數給固定住(也就是設定預設值),返回一個新的函式,呼叫這個新的函式會更簡單。
int3 = functools.partial(int, base=2)
print(int3("100"))
#在建立偏函式的時候,實際上固定了關鍵字引數base
#結果
4

例2

import functools
max2 = functools.partical(max, 10)
#實際上會把10作為*args的一部分自動加到左邊
max2(5, 6, 7)
相當於
args =(10, 5, 6, 7)
max(args)

相關文章