Python Function Decorator學習紀錄

Posted by Kubeguts on 2023-01-14

透過此篇與幾個範例了解一下python decorator的用法

範例1. 定義基本的decorator function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Decorator function
def decorator_func(callback):
def decorate():
print("Decorate the function!")
callback()

# 如果有function (亦即為callback的function instance)添加的decorator_func這個裝飾器
# 那就執行裝飾器內的decorate()函式
return decorate()

# decorator_func裝飾器會將hello_func()當成是callback function 並在decorate()內呼叫
@decorator_func
def hello_func():
print("hello")

執行結果

1
2
Decorate the function!
hello

範例2. 定義可重複使用的decorator function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# calculate(): 計算1+2+...10
def calculate_decorator(callback):
def run():
result=0

for n in range(10):
result+=n
callback(result)

return run

# 透過decorator重複使用calculate裝飾器,可用print出不同語言的敘述
@calculate_decorator
def en_calculate(result_from_calculate_decorator):
print("The result for calculating 1 to 10 is ", result_from_calculate_decorator)

@calculate_decorator
def ch_calculate(result_from_calculate_decorator):
print("計算1 to 10 是 ", result_from_calculate_decorator)

en_calculate()

執行結果

1
2
The result for calculating 1 to 10 is  45
計算1 to 1045

範例3. 定義decorator的參數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 定義一個變數叫做number,從1加到number
def define_number_for_calculator_decorator(number):
# 把原本的calculate_decorator當成內部的function,當收到number參數後直接當作其變數使用
# number就可以在run()內被range給接受了
def calculate_decorator(callback):
def run():
result=0

for n in range(number):
result+=n
callback(result)

return run

# 記得return原本的decorator function,就跟原本範例的作法一樣了
# (caluculate_decorator又作為en_calculate, ch_calculate的裝飾器)
return calculate_decorator

# 透過decorator重複使用calculate裝飾器,可用print出不同語言的敘述
@define_number_for_calculator_decorator(50)
def en_calculate(result_from_calculate_decorator):
print("The result for calculating 1 to 50 is ", result_from_calculate_decorator)

@define_number_for_calculator_decorator(50)
def ch_calculate(result_from_calculate_decorator):
print("計算1 to 50 是 ", result_from_calculate_decorator)

en_calculate()
ch_calculate()

Decorator搭配parameter示意圖

decorator_parameters

小結

以上範例可以了解python decorator的用法,
其實在很多專案都可以看到decorator的身影
例如flask定義路由`@app.route(’/’),或是kubeflow定義pipeline都會看到decorator的身影

flask

1
2
3
4
5
6
7
8
9
10
11
@app.route('/')
def index():
return 'Index Page'

@app.route('/hello')
def hello():
return 'Hello, Flask'

@app.route('/about/')
def hello():
return 'about Flask'

kubeflow pipeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@dsl.pipeline(
name='calculation-pipeline',
description='A toy pipeline that performs arithmetic calculations.'
)
def calc_pipeline(
a=7,
b=8,
c=17,
):
#Passing pipeline parameter and a constant value as operation arguments
add_task = add_op(a, 4) #Returns a dsl.ContainerOp class instance.

#Passing a task output reference as operation arguments
#For an operation with a single return value, the output reference can be accessed using `task.output` or `task.outputs['output_name']` syntax
divmod_task = divmod_op(add_task.output, b)

#For an operation with a multiple return values, the output references can be accessed using `task.outputs['output_name']` syntax
result_task = add_op(divmod_task.outputs['quotient'], c)

Reference