Static method trong Python
Trong bài viết nhanh này, chúng ta sẽ học cách tạo và sử dụng một static method trong Python. Chúng ta cũng sẽ xem xét những ưu điểm và nhược điểm mà static method mang lại so với instance method. Hãy bắt đầu cùng tìm hiểu nhé!
Static method là gì?
Static method trong Python cực kỳ giống với Python class level methods. Sự khác biệt là một static method được liên kết với một lớp thay vì các object (đối tượng) của lớp đó. Điều này có nghĩa là một static method có thể được gọi mà không cần một object của lớp đó.
Nó cũng có nghĩa là static method không thể sửa đổi trạng thái của một object vì chúng không được liên kết với nó. Hãy xem cách chúng ta có thể tạo static method trong Python.
Tại sao và khi nào nên sử dụng static method
Static method hữu ích khi bạn muốn:
- Nhóm các hàm tiện ích trong một lớp mà về mặt logic thuộc về nhau.
- Tạo các phương thức không cần truy cập vào attributes (thuộc tính) hoặc các phương thức của instance.
- Triển khai chức năng thuộc về một lớp về mặt khái niệm nhưng không yêu cầu một instance.
- Phương thức hỗ trợ hoạt động trên các class attributes thay vì instance attributes.
- Tổ chức namespace và cải thiện khả năng đọc mã bằng cách giữ các hàm liên quan trong một lớp.
- Tạo các factory methods có thể trả về các instances khác nhau của lớp dựa trên parameters.
- Thực hiện các thao tác liên quan đến lớp nhưng không cần truy cập hoặc sửa đổi class state.
- Tránh tạo các instances không cần thiết khi bạn chỉ cần gọi một hàm.
Static method đặc biệt phổ biến trong utility classes (lớp tiện ích), factory pattern implementations, và cho các operations mà về mặt khái niệm có liên quan đến một lớp nhưng không phụ thuộc vào dữ liệu cụ thể của instance.
Tạo python static method
Python Static method có thể được tạo theo hai cách. Hãy xem từng cách ở đây:
Sử dụng staticmethod()
Hãy đi thẳng vào đoạn code mẫu về cách sử dụng phương pháp staticmethod():
class Calculator:
def addNumbers(x, y):
return x + y
# create addNumbers static method
Calculator.addNumbers = staticmethod(Calculator.addNumbers)
print('Product:', Calculator.addNumbers(15, 110))
Lưu ý rằng chúng ta đã gọi addNumbers mà chúng ta đã tạo mà không cần một object. Khi chúng ta chạy chương trình này, đây là đầu ra chúng ta sẽ nhận được:

Không có gì ngạc nhiên ở đây. Cách tiếp cận này được kiểm soát vì ở mỗi nơi, có thể tạo một static method từ một class method. Hãy xem một cách tiếp cận khác với cùng một ví dụ ở đây.
Sử dụng @staticmethod
Đây là một cách tinh tế hơn để tạo một Static method vì chúng ta không phải dựa vào một định nghĩa câu lệnh của một phương thức là một class method và làm cho nó tĩnh ở mỗi nơi bạn làm cho nó tĩnh. Hãy sử dụng annotation này trong một đoạn mã:
class Calculator:
# create addNumbers static method
@staticmethod
def addNumbers(x, y):
return x + y
print('Product:', Calculator.addNumbers(15, 110))
Khi chúng ta chạy chương trình này, đây là đầu ra chúng ta sẽ nhận được:

Đây thực sự là một cách tốt hơn nhiều để tạo một static method vì ý định giữ cho phương thức tĩnh là rõ ràng ngay khi chúng ta tạo nó và đánh dấu nó bằng annotation @staticmethod.
Ưu điểm của Python static method
Static methods có một use-case rất rõ ràng. Khi chúng ta cần một số chức năng không liên quan đến một object mà liên quan đến toàn bộ lớp, chúng ta làm cho một phương thức tĩnh. Điều này khá thuận lợi khi chúng ta cần tạo các Utility methods vì chúng thường không gắn với vòng đời của đối tượng. Cuối cùng, lưu ý rằng trong một static method, chúng ta không cần self được truyền làm đối số đầu tiên. API Reference: Python Documentation.
Các trường hợp sử dụng thực tế
Nhóm các hàm tiện ích bên trong một class namespace
Static method đặc biệt hữu ích cho việc nhóm các hàm tiện ích có liên quan đến một lớp nhưng không yêu cầu truy cập vào class hoặc instance state. Cách tiếp cận này giúp giữ cho namespace sạch sẽ và có tổ chức, giúp dễ hiểu và sử dụng lớp hơn. Ví dụ, hãy xem xét một lớp StringUtilities cung cấp các phương thức thao tác chuỗi khác nhau. Bạn có thể định nghĩa một static method strip_punctuation để loại bỏ dấu câu khỏi một chuỗi, vì đó là một hàm tiện ích không phụ thuộc vào bất kỳ class hoặc instance state nào.
class StringUtilities:
@staticmethod
def strip_punctuation(input_string):
# Implementation to remove punctuation from the input string
pass
Bằng cách sử dụng một static method, bạn có thể gọi StringUtilities.strip_punctuation mà không cần tạo một instance của lớp, làm cho nó trở thành một hàm tiện ích tiện lợi.
Tạo logic có thể tái sử dụng mà về mặt logic gắn với một lớp nhưng không cần class hoặc instance state
Static methods lý tưởng để tạo reusable logic (logic có thể tái sử dụng) về mặt khái niệm được gắn với một lớp nhưng không yêu cầu truy cập vào class hoặc instance state. Điều này đặc biệt hữu ích khi bạn cần thực hiện các operations liên quan đến lớp nhưng không phụ thuộc vào dữ liệu cụ thể của instance.
Ví dụ, hãy xem xét một lớp MathUtilities cung cấp các mathematical operation (phép toán). Bạn có thể định nghĩa một static method calculate_factorial để tính giai thừa của một số, vì đó là một mathematical operation không dựa vào bất kỳ class hoặc instance state nào.
class MathUtilities:
@staticmethod
def calculate_factorial(number):
# Implementation to calculate the factorial of the input number
pass
Bằng cách sử dụng một static method, bạn có thể gọi MathUtilities.calculate_factorialmà không cần tạo một instance của lớp, làm cho nó trở thành một phần logic có thể tái sử dụng được gắn với lớp về mặt khái niệm.
Lỗi thường gặp và cách gỡ lỗi
Quên sử dụng decorator @staticmethod
Một lỗi phổ biến là quên sử dụng decorator @staticmethod khi định nghĩa một static method. Điều này có thể dẫn đến nhầm lẫn và lỗi, vì phương thức sẽ không được nhận dạng là tĩnh nếu không có decorator. Ví dụ, hãy xem xét cách triển khai không chính xác sau đây:
class Calculator:
def addNumbers(x, y):
return x + y
Trong trường hợp này, addNumbers không phải là một static method vì nó thiếu decorator @staticmethod. Để khắc phục điều này, bạn sẽ thêm decorator như sau:
class Calculator:
@staticmethod
def addNumbers(x, y):
return x + y
Nhầm lẫn static methods với class methods
Một lỗi phổ biến khác là nhầm lẫn static method với class method. Mặc dù cả hai loại phương thức đều được liên kết với một lớp, nhưng chúng có các use cases và hành vi khác nhau. Static method không yêu cầu truy cập vào class hoặc instance state, trong khi class methods thì có. Hiểu sự khác biệt giữa hai loại phương thức này là rất quan trọng để sử dụng hiệu quả.
Ví dụ, hãy xem xét một lớp Person với một static method get_average_age tính tuổi trung bình của tất cả mọi người, và một class method get_person_count trả về tổng số người. Phương thức get_average_age không yêu cầu truy cập vào bất kỳ instance state nào, làm cho nó trở thành một lựa chọn tốt cho một static method. Mặt khác, get_person_count yêu cầu truy cập vào class state để đếm tổng số người, làm cho nó trở thành một lựa chọn tốt cho một class method.
class Person:
person_count = 0
@staticmethod
def get_average_age():
# Implementation to calculate the average age of all persons
pass
@classmethod
def get_person_count(cls):
return cls.person_count
Bằng cách hiểu sự khác biệt giữa static và class method, bạn có thể sử dụng chúng một cách hiệu quả để tổ chức mã của mình và tránh các lỗi phổ biến.
Biểu đồ so sánh giữa các loại phương thức
| Kiểu phương thức | Use Case | Truy cập vào trạng thái lớp | Truy cập vào trạng thái instance |
|---|---|---|---|
| Static Method | Hàm tiện ích | Không | Không |
| Class Method | Factory methods | Có | Không |
| Instance Method | Phương thức thông thường | Có | Có |
Ví dụ
Ví dụ về Static Method
class MathUtilities:
@staticmethod
def calculate_factorial(number):
# Implementation to calculate the factorial of the input number
pass
Trong ví dụ này, calculate_factorial là một static method có thể được gọi mà không cần tạo một instance của lớp MathUtilities. Nó không có quyền truy cập vào class hoặc instance state.
Ví dụ về Class Method
class Person:
person_count = 0
@classmethod
def add_person(cls):
cls.person_count += 1
return cls()
Trong ví dụ này, add_person là một class method có quyền truy cập vào class state (biến lớp person_count). Nó không có quyền truy cập vào instance state.
Ví dụ về Instance Method
class Person:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, my name is {self.name}!")
Trong ví dụ này, greet là một instance method có quyền truy cập vào instance state. Nó cũng có quyền truy cập vào class state, nhưng nó không được hiển thị trong ví dụ này.
Phần hỏi đáp
1. Static method trong Python là gì?
Một static method trong Python là một phương thức thuộc về một lớp thay vì một instance của lớp đó. Điều này có nghĩa là nó có thể được gọi trực tiếp trên chính lớp, mà không cần phải tạo một instance của lớp. Static method về cơ bản là các hàm tiện ích được nhóm trong một lớp cho mục đích tổ chức.
Ví dụ:
class MathUtilities:
@staticmethod
def calculate_factorial(number):
# Implementation to calculate the factorial of the input number
pass
# Calling a static method without creating an instance
MathUtilities.calculate_factorial(5)
2. Static method khác với class method như thế nào?
Một static method không có quyền truy cập vào class hoặc instance state, trong khi một class method có quyền truy cập vào class state. Điều này có nghĩa là một static method không thể sửa đổi hoặc sử dụng các biến lớp hoặc instance, trong khi một class method có thể sửa đổi các biến lớp.
Ví dụ:
class MyClass:
class_var = "This is a class variable"
@staticmethod
def static_method():
# This method cannot access or modify class_var
pass
@classmethod
def class_method(cls):
# This method can access and modify class_var
cls.class_var = "This is a modified class variable"
pass
3. Khi nào tôi nên sử dụng một static method trong Python?
Sử dụng một static method khi bạn cần một hàm tiện ích có liên quan đến một lớp nhưng không yêu cầu truy cập vào class hoặc instance state. Điều này đặc biệt hữu ích cho việc nhóm các hàm tiện ích không cụ thể cho một instance nhưng có liên quan đến lớp.
Ví dụ:
class StringUtilities:
@staticmethod
def is_palindrome(s):
# Implementation to check if a string is a palindrome
pass
# Using a static method to check if a string is a palindrome
StringUtilities.is_palindrome("radar")
4. Một static method có thể truy cập các biến instance không?
Không, một static method không thể truy cập các biến instance vì nó không được liên kết với một instance của lớp. Nó chỉ có thể truy cập các biến lớp nếu chúng được truyền rõ ràng làm đối số.
Ví dụ:
class MyClass:
def __init__(self, instance_var):
self.instance_var = instance_var
@staticmethod
def static_method(instance_var):
# This method can access instance_var if it is passed as an argument
pass
# Creating an instance and passing the instance variable to the static method
my_instance = MyClass("This is an instance variable")
MyClass.static_method(my_instance.instance_var)
5. Tại sao nên sử dụng static methods thay vì các hàm thông thường?
Sử dụng static method thay vì các hàm thông thường khi bạn muốn nhóm các hàm tiện ích trong một lớp để tổ chức và dễ đọc hơn. Điều này đặc biệt hữu ích khi các hàm tiện ích có liên quan chặt chẽ đến lớp nhưng không yêu cầu truy cập vào class hoặc instance state.
Kết luận
Static method là một công cụ hữu ích trong Python để tổ chức các hàm tiện ích trong một lớp. Chúng đặc biệt hữu ích cho việc nhóm các hàm tiện ích không cụ thể cho một instance nhưng có liên quan đến lớp. Chúng có thể được tạo bằng cách sử dụng decorator @staticmethod hoặc hàm staticmethod().
