@ ตามด้วยชื่อฟังก์ชัน ฟังก์ชันนั้นก็จะกลายเป็นเดคอเรเตอร์ของคลาสที่จะประกาศขึ้นมานี้def sai_y(c):
c.y = 'วาย'
return c
@sai_y
class mi_x:
x = 'เอ็กซ์'
print(mi_x.y) # ได้ วาย
mi_x ถูกสร้างขึ้นโดยมีแอตทริบิวต์แค่ x เท่านั้น แต่เพราะแต่งด้วย sai_y ซึ่งเป็นเดคอเรเตอร์สำหรับใส่แอตทริบิวต์ชื่อ y เข้าไปให้กับคลาส ดังนั้นก็เลยมีแอตทริบิวต์ yfunctools.wraps ช่วยdef phoemngoenduean5000(c):
c.ngoenduean += 5000
return c
@phoemngoenduean5000
class Phanakngan:
ngoenduean = 26000
print(Phanakngan.ngoenduean) # ได้ 31000
def phoemngoenduean(ngoen):
def phoem(c):
c.ngoenduean += ngoen
return c
return phoem
@phoemngoenduean(17000)
class Phuchatkan:
ngoenduean = 56000
print(Phuchatkan.ngoenduean) # ได้ 73000
phoemngoenduean (เพิ่มเงินเดือน) เป็นฟังก์ชันสำหรับสร้างเดคอเรเตอร์ที่เพิ่มเงินเดือนตามตัวเลขที่ใส่เข้าไปdef deko(m):
def boko(*arg):
return '<~~' + m(*arg) + '~~>'
return boko
class Kiradeko:
soba = '=~~.'
@deko
def kira(self,xkira):
return self.soba + xkira + ''.join(reversed(self.soba))
l = Kiradeko()
print(l.kira('แอลคิระ')) # ได้ <~~=~~.แอลคิระ.~~=~~>
deko ในตัวอย่างนี้ก็คล้ายกับ deko ในบทที่ ๓๐ ในที่นี้ deko ทำหน้าที่เป็นเดคอเรเตอร์ให้กับเมธอด kira ภายในคลาส Kiradekoclass Kiradeko:
soba = '=~~.'
def deko(m):
def boko(*arg):
return '<~~' + m(*arg) + '~~>'
return boko
@deko
def kira(self,xkira):
return self.soba + xkira + ''.join(reversed(self.soba))
() ไว้ข้างหลังเพื่อเรียกใช้งานได้f = d(f) โดยที่ f คือฟังก์ชันหรือคลาสที่ถูกแต่ง ส่วน d คือเดคอเรเตอร์() ได้ก็สามารถเป็นเดคอเรเตอร์ได้เช่นกัน@type
def f1():
return 1
print(f1) # ได้ <class 'function'>
type ซึ่งเป็นคลาสมาเป็นเดคอเรเตอร์ ผลที่ได้ก็คือเหมือนการที่นิยามฟังก์ชัน f1 ขึ้นเสร็จแล้วก็พิมพ์ f1 = type(f1) ต่อ ดังนั้น f1 ก็เลยถูกแทนด้วยคลาสของ f1 ก็คือ functiontype นั้นปกติมักถูกใช้ในฐานะฟังก์ชัน แต่จริงๆแล้ว type เป็นคลาสคลาสหนึ่ง อินสแตนซ์ของ type ก็คือคลาสหรือชนิดต่างๆของออบเจ็กต์ ดังนั้นเมื่อใช้ type(ออบเจ็กต์) แล้วเราได้ค่าออกมาเป็นตัวคลาสของออบเจ็กต์นั้น ที่จริงแล้วคลาสที่ได้มานั้นเป็นผลจากกระบวนการสร้างอินสแตนซ์ของ typeclass Cla:
def __init__(self,f):
self.f = f
@Cla
def f2():
return 'ff'
print(f2) # ได้ <__main__.Cla object at 0x1124f9ac8>
print(f2.f) # ได้
print(f2.f()) # ได้ ff
f2 = Cla(f2) ซึ่งโดยปกติแล้วจะถือเป็นการสร้างอินสแตนซ์f2 เดิมนั้นจะถูกใช้เป็นพารามิเตอร์ f ในเมธอด __init__ แล้วก็กลายมาเป็นแอตทริบิวต์หนึ่งของ self ซึ่งก็คืออินสแตนซ์ที่จะได้ออกมาf2.f ก็เลยกลายเป็นตัวฟังก์ชัน f2 เดิม ซึ่งเมื่อเติม () ไปข้างหลังก็จะทำงานในฐานะฟังก์ชันได้ตามปกติและให้ค่า ff ออกมาclass Deka:
def __init__(self,f):
def f0(x):
return '$$' + f(x) + '$$'
def f1(x):
return '<~^' + f(x) + '^~>'
def f2(x):
return '(((' + f(x) + ')))'
self.deka = [f0,f1,f2]
@Deka
def kirei(x):
return '=' + x + '='
print(kirei.deka[0]('kirei')) # ได้ $$=kirei=$$
print(kirei.deka[1]('kirei')) # ได้ <~^=kirei=^~>
print(kirei.deka[2]('kirei')) # ได้ (((=kirei=)))
Deka จะทำการแต่งให้ kirei กลายเป็นออบเจ็กต์ซึ่งภายในมีฟังก์ชัน (เมธอด) ซึ่งถูกนิยามขึ้น ๓ อันเก็บอยู่เป็นลิสต์ในตัวแปร deka@property, @classmethod และ @staticmethod สำหรับ ๒ ตัวหลังจะกล่าวถึงในบทหน้า@property นั้นเนื่องจากค่อนข้างเข้าใจยากและไม่ได้ถึงขั้นจำเป็นจะขอแยกไปอยู่ใน เนื้อหาเสริม >> สร้างแอตทริบิวต์ที่มีคุณสมบัติพิเศษในคลาสด้วย propertyติดตามอัปเดตของบล็อกได้ที่แฟนเพจ