Các phương thức @classmethod, @staticmethod và @property trong Python

Trong lập trình hướng đối tượng Python, ba decorator @classmethod, @staticmethod@property giúp định nghĩa hành vi đặc biệt cho các phương thức trong lớp. Dưới đây là cách chúng hoạt động và khác biệt giữa chúng.

Phương thức tĩnh (@staticmethod)

Được dùng khi bạn muốn một hàm thuộc về lớp nhưng không cần truy cập đến trạng thái của lớp hay đối tượng. Không yêu cầu tham số mặc định như self hay cls.

class Calculator:
    @staticmethod
    def multiply(a, b):
        return a * b

# Gọi qua lớp
print(Calculator.multiply(5, 3))  # 15

# Gọi qua đối tượng
calc = Calculator()
print(calc.multiply(4, 6))        # 24

Lưu ý: Vì không nhận self, nên không thể truy cập thuộc tính hay phương thức của đối tượng. Nếu cần, bạn phải truyền đối tượng vào thủ công.

class Animal:
    def __init__(self, species):
        self.species = species

    @staticmethod
    def describe(animal_instance, food):
        print(f"{animal_instance.species} đang ăn {food}")

dog = Animal("Chó")
Animal.describe(dog, "xương")  # Chó đang ăn xương

Phương thức lớp (@classmethod)

Nhận tham số đầu tiên là cls — đại diện cho chính lớp đó. Dùng để tạo factory method hoặc truy cập thuộc tính/métod cấp lớp.

class Vehicle:
    brand = "Toyota"

    @classmethod
    def show_brand(cls):
        print(f"Thương hiệu: {cls.brand}")

    @classmethod
    def create_default(cls):
        return cls()

car = Vehicle.create_default()
Vehicle.show_brand()   # Thương hiệu: Toyota
car.show_brand()       # Thương hiệu: Toyota

Bạn cũng có thể gọi các phương thức khác trong lớp thông qua cls:

class Message:
    @classmethod
    def send(cls, text):
        instance = cls()
        instance.display(text)

    def display(self, msg):
        print(f"[Thông báo]: {msg}")

Message.send("Xin chào!")  # [Thông báo]: Xin chào!

Quan trọng: @classmethod chỉ truy cập được biến lớp, không truy cập được biến thực thể (instance variable).

Thuộc tính (@property)

Biến một phương thức thành thuộc tính, cho phép truy cập như biến bình thường (không cần dấu ngoặc). Thường dùng để kiểm soát việc đọc/ghi/xóa dữ liệu.

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value > 0:
            self._radius = value
        else:
            raise ValueError("Bán kính phải lớn hơn 0")

    @radius.deleter
    def radius(self):
        self._radius = 0

c = Circle(5)
print(c.radius)           # 5 (gọi như thuộc tính)
c.radius = 10             # Gán giá trị mới
print(c.radius)           # 10
del c.radius              # Xóa (gán 0)
print(c.radius)           # 0

Tóm tắt:

  • @property: getter — truy xuất giá trị
  • @.setter: setter — gán giá trị mới
  • @.deleter: deleter — xử lý khi xóa thuộc tính

Thẻ: python classmethod staticmethod property oop

Đăng vào ngày 30 tháng 5 lúc 02:43