Properties และ Class Methods
Decorator @property
หัวข้อที่มีชื่อว่า “Decorator @property”@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._celsiusSetters
หัวข้อที่มีชื่อว่า “Setters”จับคู่ @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
Computed (derived) properties
หัวข้อที่มีชื่อว่า “Computed (derived) properties”Property คำนวณค่าตอนถูกเรียกได้ โดยไม่ต้องมีพื้นที่จัดเก็บเบื้องหลัง:
@property def fahrenheit(self) -> float: return self._celsius * 9 / 5 + 32t.fahrenheit ดูเหมือน plain attribute สำหรับผู้เรียก แต่คำนวณใหม่ทุกครั้ง
@classmethod — alternative constructors
หัวข้อที่มีชื่อว่า “@classmethod — alternative constructors”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.0Subclass สืบทอด class method อัตโนมัติและ cls จะอ้างถึง subclass — factory จึงสร้าง instance ของ type ที่ถูกต้อง
@staticmethod — utility functions
หัวข้อที่มีชื่อว่า “@staticmethod — utility functions”Static method ไม่รับทั้ง instance และ class ใช้สำหรับ utility ที่อยู่ใน class ตามตรรกะแต่ไม่ต้องการ access state ของ class หรือ instance:
@staticmethod def absolute_zero() -> float: return -273.15print(Temperature.absolute_zero()) # -273.15Demo รันได้จริง
หัวข้อที่มีชื่อว่า “Demo รันได้จริง”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 = 0print(t.fahrenheit)t2 = Temperature.from_fahrenheit(212)print(t2.celsius)print(Temperature.absolute_zero())Loading Python runtime (first run only)…