0Pricing
Python Academy · บทเรียน

เดคอเรเตอร์ @property

ใช้ property สำหรับ getter, setter และ deleter

เดคอเรเตอร์ @property เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

บทนำ

@property เปลี่ยนเมธอดให้เป็นแอตทริบิวต์ที่อ่านได้ ส่วน @setter และ @deleter ช่วยเติมรูปแบบการเข้าถึงที่ควบคุมได้ให้สมบูรณ์

เหตุใดจึงใช้ @property

แทนที่จะใช้ getX()/setX() แบบ Java Python ใช้ @property ทำให้การเข้าถึงดูเหมือนแอตทริบิวต์: obj.value ไม่ใช่ obj.get_value()
class Circle:
    def __init__(self, r): self._r = r
    @property
    def radius(self): return self._r
c = Circle(5)
print(c.radius)  # no ()

พร็อพเพอร์ตีที่คำนวณค่า

เมธอดที่ใช้ @property จะคำนวณค่าเมื่อถูกเรียกใช้ obj.area จะคำนวณใหม่ทุกครั้งที่เข้าถึง โดยไม่จำเป็นต้องเก็บค่าไว้
import math
class Circle:
    def __init__(self, r): self._r = r
    @property
    def area(self): return math.pi * self._r**2
c = Circle(5)
print(round(c.area, 2))

Setter ของพร็อพเพอร์ตี

@property_name.setter จะเพิ่ม setter ให้กับพร็อพเพอร์ตี จากนั้น c.radius = 10 จะเรียกใช้เมธอด setter
class Circle:
    def __init__(self, r): self._r = r
    @property
    def radius(self): return self._r
    @radius.setter
    def radius(self, val):
        if val <= 0: raise ValueError('radius must be positive')
        self._r = val
c = Circle(5)
c.radius = 10
print(c.radius)

Deleter ของพร็อพเพอร์ตี

@property_name.deleter จัดการคำสั่ง del obj.attr และเหมาะสำหรับตรรกะการล้างข้อมูล
class User:
    def __init__(self, name): self._name = name
    @property
    def name(self): return self._name
    @name.deleter
    def name(self): del self._name
u = User('Alice')
del u.name
print(hasattr(u, '_name'))

พร็อพเพอร์ตีแบบอ่านอย่างเดียว

กำหนดเฉพาะ getter โดยไม่กำหนด setter หากพยายามกำหนดค่า จะเกิด AttributeError
class Const:
    def __init__(self, v): self._v = v
    @property
    def value(self): return self._v
c = Const(42)
print(c.value)
try: c.value = 99
except AttributeError as e: print(e)

พร็อพเพอร์ตีพร้อมการตรวจสอบข้อมูล

Setter เป็นตำแหน่งที่เหมาะอย่างยิ่งสำหรับตรวจสอบข้อมูล เช่น ตรวจสอบชนิด ช่วงค่า หรือรูปแบบก่อนจัดเก็บ
class BoundedInt:
    def __init__(self, lo, hi): self.lo,self.hi=lo,hi; self._v=lo
    @property
    def value(self): return self._v
    @value.setter
    def value(self, v):
        if not self.lo <= v <= self.hi:
            raise ValueError(f'{v} out of [{self.lo},{self.hi}]')
        self._v = v
b = BoundedInt(0, 10)
b.value = 5
print(b.value)

การแคชด้วย property

ใช้ @property ร่วมกับค่าที่แคชไว้เพื่อคำนวณเพียงครั้งเดียวและจดจำผลลัพธ์
class Expensive:
    _cache = None
    @property
    def result(self):
        if self._cache is None:
            self._cache = sum(range(1000))
        return self._cache
e = Expensive()
print(e.result)
print(e.result)

cached_property (Python 3.8 ขึ้นไป)

@functools.cached_property จะคำนวณพร็อพเพอร์ตีเพียงครั้งเดียวแล้วเก็บไว้เป็นแอตทริบิวต์ของอินสแตนซ์ จึงไม่ต้องคำนวณซ้ำ
from functools import cached_property
import math
class Circle:
    def __init__(self, r): self.r = r
    @cached_property
    def area(self): return math.pi * self.r**2
c = Circle(5)
print(round(c.area, 2))

พร็อพเพอร์ตีกับ __slots__

__slots__ ป้องกันการสร้างแอตทริบิวต์โดยอำเภอใจและช่วยประหยัดหน่วยความจำ ส่วนพร็อพเพอร์ตีใช้เพิ่มตรรกะ ทั้งสองอย่างจึงใช้เสริมกันได้
class Point:
    __slots__ = ('_x', '_y')
    def __init__(self, x, y): self._x,self._y=x,y
    @property
    def x(self): return self._x
p = Point(1, 2)
print(p.x)

ควรใช้ @property เมื่อใด

ใช้ @property เมื่อจำเป็นต้องตรวจสอบข้อมูล มีค่าที่คำนวณขึ้น หรือจำเป็นต้องรักษาความเข้ากันได้ย้อนหลังขณะเปลี่ยนรายละเอียดภายใน
# Before: class Person:
#     def __init__(self, age): self.age = age
# After: add validation without changing caller code
class Person:
    def __init__(self, age): self.age = age
    @property
    def age(self): return self._age
    @age.setter
    def age(self, v):
        if v < 0: raise ValueError('negative age')
        self._age = v
p = Person(30)
print(p.age)

ตรวจสอบอย่างรวดเร็ว

จะเกิดอะไรขึ้นเมื่อพยายามกำหนดค่าให้กับ @property แบบอ่านอย่างเดียวที่ไม่ได้กำหนด setter ไว้

ทบทวน

@property: เปลี่ยน getter ให้เป็นการเข้าถึงแบบแอตทริบิวต์ @name.setter เพิ่มความสามารถในการเขียน @name.deleter เพิ่มความสามารถในการใช้ del @cached_property คำนวณเพียงครั้งเดียว และ setter เหมาะสำหรับการตรวจสอบข้อมูล

เรียนรู้ต่อไป

คุณมีความก้าวหน้าอย่างยอดเยี่ยม โปรดเรียนรู้ต่อไปเพื่อทำความเข้าใจแนวคิดถัดไปอย่างเชี่ยวชาญ

คำถามที่พบบ่อย

บทเรียน “เดคอเรเตอร์ @property” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เดคอเรเตอร์ @property” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เดคอเรเตอร์ @property”

ใช้ property สำหรับ getter, setter และ deleter คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “เดคอเรเตอร์ @property” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันในฐานะออบเจ็กต์ชั้นหนึ่ง
  2. การเขียนเดคอเรเตอร์แบบกำหนดเอง
  3. เดคอเรเตอร์ @property
  4. @classmethod และ @staticmethod
← กลับไปที่ Python Academy