ข้ามไปยังเนื้อหา

Properties และ Class Methods

@property เปลี่ยน method ให้เป็น attribute-style accessor ผู้เรียกใช้ obj.celsius แทน obj.get_celsius() ทำให้ public API สะอาดโดยยังเรียก validation logic ได้เบื้องหลัง

class Temperature:
def __init__(self, celsius: float = 0.0) -> None:
self._celsius = celsius # underscore = internal storage
@property
def celsius(self) -> float:
return self._celsius

จับคู่ @property กับ @name.setter เพื่อ intercept การ assign ค่า:

@celsius.setter
def celsius(self, value: float) -> None:
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
self._celsius = value

ตอนนี้ t.celsius = -300 จะ raise ValueError อัตโนมัติ หากไม่มี setter, property จะเป็น read-only — การ assign จะ raise AttributeError

Property คำนวณค่าตอนถูกเรียกได้ โดยไม่ต้องมีพื้นที่จัดเก็บเบื้องหลัง:

@property
def fahrenheit(self) -> float:
return self._celsius * 9 / 5 + 32

t.fahrenheit ดูเหมือน plain attribute สำหรับผู้เรียก แต่คำนวณใหม่ทุกครั้ง

Class method รับ class (cls) เป็น argument แรกแทน instance การใช้งานที่พบบ่อยที่สุดคือการสร้าง alternative constructors:

@classmethod
def from_fahrenheit(cls, f: float) -> "Temperature":
return cls((f - 32) * 5 / 9)
boiling = Temperature.from_fahrenheit(212)
print(boiling.celsius) # 100.0

Subclass สืบทอด class method อัตโนมัติและ cls จะอ้างถึง subclass — factory จึงสร้าง instance ของ type ที่ถูกต้อง

Static method ไม่รับทั้ง instance และ class ใช้สำหรับ utility ที่อยู่ใน class ตามตรรกะแต่ไม่ต้องการ access state ของ class หรือ instance:

@staticmethod
def absolute_zero() -> float:
return -273.15
print(Temperature.absolute_zero()) # -273.15
class Temperature:
def __init__(self, celsius: float = 0.0) -> None:
self._celsius = celsius
@property
def celsius(self) -> float:
return self._celsius
@celsius.setter
def celsius(self, value: float) -> None:
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
self._celsius = value
@property
def fahrenheit(self) -> float:
return self._celsius * 9 / 5 + 32
@classmethod
def from_fahrenheit(cls, f: float) -> "Temperature":
return cls((f - 32) * 5 / 9)
@staticmethod
def absolute_zero() -> float:
return -273.15
t = Temperature(100)
print(t.celsius)
print(t.fahrenheit)
t.celsius = 0
print(t.fahrenheit)
t2 = Temperature.from_fahrenheit(212)
print(t2.celsius)
print(Temperature.absolute_zero())
`@property` ทำอะไรกับ method?
จะทำให้ `@property` เขียนได้อย่างไร?
parameter แรกของ `@classmethod` คืออะไร?
`@staticmethod` เหมาะสมเมื่อใด?