มาลองดูสิว่า decorator ทำงานยังไง
จากตัวอย่างในบทความก่อนหน้านี้ เมื่อเรียก func1() จะไปที
@entryExit
def func1():
print "inside func1()"
result = linkfunc()
print "result = ",result
step การทำงาน เมื่อเรียก func1() แล้ว
1. จะไปทำที่ decorator ก่อน ตัว f ที่อยู่ใน def entryExit(f): จะเก็บว่าเรียก decorator มาจาก function ไหน (เท่าที่เข้าใจเองนะ)
def entryExit(f):
def new_f():
print "Entering", f.__name__
f()
print "Exited", f.__name__
print "--------------"
return new_f
2. เมื่อทำงานใน decorator แล้วเจอ f() ก็จะกลับไปทำงานที่ function ที่เรียกมาก่อน ( ขอเรียกว่า func main ) แล้วถึงจะกลับมาทำที่ decorator ต่อ
หากที่ def new_f(*args, **kw): ตอนที่เรียกกลับไปทำงานที่ func main จะต้องใส่ค่า *args, **kw ไปด้วย คือ f(*args, **kw)
โดยใน decor สามารถมีได้หลาย เช่น
def entryExit(f):
def new_f():
print "Entering", f.__name__
f()
print "Exited", f.__name__
print "--------------"
def new_z():
print "New ZZZ",f.__name__
new_f()
return new_z
ซึ่ง decor จะเลือกทำ func ที่ทำการ return ในตัวอย่างนี้คือ return new_z ก็จะไปทำงานที่ def new_z
การแยกหลาย func ใน decor ก็ทำได้นะ คงเพื่อให้เป็นระเบียบ (หรือป่าว)
แต่ว่าเค้าไม่นิยมทำกัน ใน decor เค้าจะมีแค่ func เดียว
>>ผลลัพธ์หลังจากเข้ามาที่ decor คือ
New ZZZ func1
Entering func1
3. เมื่อมีการเรียกกลับโดยใช้ f() เพื่อไปที่ func main (คือ func ที่มี decor แปะอยู่) ในตัวอย่างคือ
@entryExit
def func1():
print "inside func1()"
result = linkfunc()
print "result = ",result
โดยใน func1 นี้ ก็สามารถเรียกไปทำงานที่ func อื่นได้ด้วย ในตัวอย่างนี้ก็เรียกไปที่ linkfunc() ซึ่งก็จะทำการ
print "--link func--"
a = 'aa'
และ linkfunc() ก็คืนค่า a กลับมา
>>ผลลัพธ์
Entering func1
inside func1()
--link func--
result = aa
4. เมื่อจบการทำงานที่ func1 แล้ว แต่ว่าที่ decor ยังไม่เสร็จมันก็กลับไปทำที่ decor ต่อจากตรง f() ที่เรียกไปนั้น
ในตัวอย่างนี้ก็คือกลับมา print ต่อ
print "Exited", f.__name__
print "--------------"
>>ผลลัพธ์จนจบการทำงานของการเรียก func1() นี้คือ
Entering func1
inside func1()
--link func--
result = aa
Exited func1
--------------
พอก่อนละนะเรื่อง decorator เอาแค่นี้ดีก่า ^_^
ไม่มีความคิดเห็น:
แสดงความคิดเห็น