Menu
CoddyTech

Phương thức tĩnh và phương thức lớp

Thuộc phần Lập trình hướng đối tượng trong hành trình Python của Coddy. Bài học 39 trên 64.

Ngoài các phương thức thông thường của đối tượng, lớp còn có thể có phương thức tĩnh và phương thức lớp để phục vụ những mục đích khác nhau.

Đây là ví dụ về một phương thức tĩnh:

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def is_even(number):
        return number % 2 == 0

Phương thức tĩnh không cần self và hoạt động như các hàm thông thường. Gọi chúng trực tiếp từ lớp:

result = MathHelper.add(5, 3)
print(result)

check = MathHelper.is_even(10)
print(check)

Đây là ví dụ về một phương thức của lớp:

class Person:
    count = 0  # Biến lớp
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

Phương thức lớp nhận chính lớp đó (cls) làm tham số đầu tiên:

person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_count())  # 2

Dùng phương thức lớp như các hàm khởi tạo thay thế:

anonymous = Person.create_anonymous()
print(anonymous.name)      # Anonymous
print(Person.get_count())  # 3

So sánh cả ba loại phương thức trong một lớp:

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # Phương thức instance (instance method): cần self để truy cập dữ liệu của instance
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # Phương thức lớp (class method): cần cls để truy cập dữ liệu của lớp
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # Phương thức tĩnh (static method): không cần self hay cls, chỉ là một hàm tiện ích (function)
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Thuộc về Alice
print(Calculator.get_brand())   # Python Calc
print(Calculator.multiply(4, 5)) # 20

Đầu ra:

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

Bạn cũng có thể gọi các phương thức lớp và phương thức tĩnh từ các đối tượng:

calc = Calculator("Bob")
print(calc.get_brand())      # Python Calc
print(calc.multiply(2, 3))   # 6

Điểm khác biệt chính:

  • Phương thức của đối tượng: Cần self, truy cập dữ liệu của đối tượng
  • Phương thức của lớp: Cần cls, truy cập dữ liệu của lớp, phù hợp để làm hàm khởi tạo thay thế
  • Phương thức tĩnh: Không cần cả hai, chỉ là các hàm tiện ích liên quan đến lớp

Điểm chính: Dùng @staticmethod cho các hàm tiện ích thuộc về lớp về mặt logic nhưng không cần dữ liệu của lớp hoặc đối tượng. Dùng @classmethod khi bạn cần truy cập chính lớp đó, chẳng hạn như khi tạo hàm khởi tạo thay thế hoặc truy cập các biến của lớp.

challenge icon

Thử thách

Dễ

Trong thử thách này, bạn sẽ triển khai lớp Temperature với các chức năng cụ thể, đồng thời tận dụng framework kiểm thử toàn diện.

Bạn chỉ cần chỉnh sửa tệp temperature.py, làm theo các chú thích TODO hướng dẫn cách triển khai. Lớp này cần có:

  • Một biến lớp để theo dõi các số đo nhiệt độ
  • Một phương thức tĩnh để chuyển đổi nhiệt độ
  • Các phương thức lớp để thêm số đo và tính giá trị trung bình

Tự làm thử

from temperature import Temperature

# Bộ xử lý test case để kiểm thử toàn diện
test_case = input()

if test_case == "default_test":
    # Kiểm tra chức năng cơ bản
    Temperature.celsius_readings = []
    Temperature.add_reading(25)
    Temperature.add_reading(30)
    Temperature.add_reading(27)
    
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"22°C is {Temperature.celsius_to_fahrenheit(22)}°F")

elif test_case == "empty_readings":
    # Kiểm tra average_reading khi không có số đo nào
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # Kiểm tra với một số đo duy nhất
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # Kiểm tra với các giá trị nhiệt độ âm
    Temperature.celsius_readings = []
    Temperature.add_reading(-10)
    Temperature.add_reading(-20)
    Temperature.add_reading(-30)
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"-15°C is {Temperature.celsius_to_fahrenheit(-15)}°F")

elif test_case == "zero_value":
    # Kiểm tra với số đo 0°C
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # Kiểm tra với các giá trị nhiệt độ cực đoan
    absolute_zero = -273.15  # Độ không tuyệt đối tính theo độ C
    sun_surface = 5500  # Nhiệt độ xấp xỉ trên bề mặt Mặt Trời tính theo độ C
    
    print(f"{absolute_zero}°C is {Temperature.celsius_to_fahrenheit(absolute_zero)}°F")
    print(f"{sun_surface}°C is {Temperature.celsius_to_fahrenheit(sun_surface)}°F")

elif test_case == "reset_readings":
    # Kiểm tra việc đặt lại các số đo
    Temperature.celsius_readings = []
    Temperature.add_reading(10)
    Temperature.add_reading(20)
    Temperature.add_reading(30)
    print(f"Average reading before reset: {Temperature.average_reading()}")
    
    Temperature.celsius_readings = []
    print(f"Average reading after reset: {Temperature.average_reading()}")

elif test_case == "decimal_values":
    # Kiểm tra với các giá trị thập phân
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # Thân nhiệt bình thường
    Temperature.add_reading(37.2)  # Sốt nhẹ
    Temperature.add_reading(36.9)  # Dao động bình thường
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # Kiểm tra với nhiều giá trị đo
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Python online