@
ตามด้วยชื่อฟังก์ชัน ฟังก์ชันนั้นก็จะกลายเป็นเดคอเรเตอร์ของคลาสที่จะประกาศขึ้นมานี้def sai_y(c):
c.y = 'วาย'
return c
@sai_y
class mi_x:
x = 'เอ็กซ์'
print(mi_x.y) # ได้ วาย
mi_x
ถูกสร้างขึ้นโดยมีแอตทริบิวต์แค่ x
เท่านั้น แต่เพราะแต่งด้วย sai_y
ซึ่งเป็นเดคอเรเตอร์สำหรับใส่แอตทริบิวต์ชื่อ y
เข้าไปให้กับคลาส ดังนั้นก็เลยมีแอตทริบิวต์ y
functools.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
ภายในคลาส Kiradeko
class 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
ก็คือ function
type
นั้นปกติมักถูกใช้ในฐานะฟังก์ชัน แต่จริงๆแล้ว type
เป็นคลาสคลาสหนึ่ง อินสแตนซ์ของ type
ก็คือคลาสหรือชนิดต่างๆของออบเจ็กต์ ดังนั้นเมื่อใช้ type(ออบเจ็กต์)
แล้วเราได้ค่าออกมาเป็นตัวคลาสของออบเจ็กต์นั้น ที่จริงแล้วคลาสที่ได้มานั้นเป็นผลจากกระบวนการสร้างอินสแตนซ์ของ type
class 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ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ