So sánh @classmethod, @staticmethod và Instance Methods trong Python
Như đã trinh bày ở bài lớp và đối tượng trong Python, các bạn sẽ thấy các phương thức được khai báo trong class đều có tham số self. Nếu không khai báo tham số này có được không? Câu trả lời là có. Phương thức chúng ta đã học gọi là instance methods. Hôm nay chúng ta sẽ tìm hiểu thêm hai loại phương thức nữa là @classmethod, @staticmethod.
Nội dung của bài
Tìm hiểu instance method trong Python
class MyClass:
# instance method
def myfunc(self):
return 'Instance method called', self
Phương thức myfunc() trong ví dụ trên được gọi là instance method (phương thức thể hiện). Tham số self trỏ đến chính đối tượng được khởi tạo từ lớp MyClass.
Thông qua tham số self, phương thức myfunc() có thể truy cập vào các thuộc tính, các phương thức khác trong cùng lớp. Điều này có nghĩa là phương thức thể hiện có thể sửa đổi trạng thái của các đối tượng.
Không những thế, instance method có thể truy cập vào class thông qua cách gọi: self.__class__. Như vậy các instance method có thể sửa đổi trạng thái của lớp.
Tìm hiểu @classmethod trong Python
class MyClass:
# instance method
def myfunc(self):
return 'Instance method called', self
@classmethod
def classmethod(cls):
return 'class method called', cls
Trong ví dụ trên chúng ta khai báo một phương thức classmethod(cls) và sử dụng Decorator là @classmethod. Việc sử dụng Decorator @classmethod là để hệ thống hiểu đây là một class method.
Kiểu phương thức này không có tham số self, thay vào đó là tham số cls, tham chiếu đến class. Tham số cls không thể sửa đổi trạng thái của các đối tượng, nhưng có thể thay đổi trạng thái của class.
Tìm hiểu @staticmethod trong Python
class MyClass:
# instance method
def myfunc(self):
return 'Instance method called', self
@classmethod
def classmethod(cls):
return 'class method called', cls
@staticmethod
def staticmethod():
return 'static method called'
Phương thức sử dụng Decorator @staticmethod là phương thức static. Phương thức này không có tham số cls hày self. Do đó, một static method không thể sửa đổi trạng thái đối tượng cũng như trạng thái của lớp.
So sánh sự khác nhau giữa ba loại phương thức
Loại Phương thức | Thay đổi trạng thái của đối tượng | Thay đổi trạng thái của lớp |
instance method | Có | Có |
@classmethod | Không | Có |
@staticmethod | Không | Không |
Để rõ hơn về sự khác biệt giữa ba loại phương thức chúng ta cùng nhàu đi vào một ví dụ cụ thể:
Chúng ta thử mô phỏng lại game Cas vs. Dog.
Ban đầu chúng ta xây dựng class Animal như sau:
class Animal:
def __init__(self, role, name, color, hp, attack, defence):
self.role = role
self.name = name
self.color = color
self.hp = hp # the animal's health points
self.attack = atk # the animal's attack power
self.defence = defence # the animal's defence power
# create instance - cat
cat = Animal('Cat', 'Tom', 'Black', 30, 15, 10)
# create instance - dog
dog = Animal('Dog', 'Scooby Doo', 'White', 35, 8, 10)
Bây giờ chúng ta xây dựng một số phương thức thể hiện hành động của nhân vật. Giả sử như xây dựng hàm giới thiệu bản thân của mỗi nhân vật trước trận đấu và giới thiệu nhân vật chiến thắng:
class Animal:
def __init__(self, role, name, color, hp, attack, defence):
self.role = role
self.name = name
self.color = color
self.hp = hp # the animal's health points
self.attack = attack # the animal's attack power
self.defence = defence # the animal's defence power
def declare(self):
print(f"I am {self.role} {self.name}. \
I am {self.color}. My HP is {self.hp}. \
My attacking power is {self.attack}. \
My defence is {self.defence}.")
def win(self):
print(f"{self.role} {self.name} Wins!")
# create instance - cat
cat = Animal('Cat', 'Tom', 'Black', 30, 15, 10)
# create instance - dog
dog = Animal('Dog', 'Scooby Doo', 'White', 35, 8, 10)
Giả sử mèo chiến thắng:
dog.declare()
# I am Dog Scooby Doo. I am White. My HP is 35. My attacking power is 8. My defence is 10.
cat.win()
#Cat Tom Wins!
Nếu chúng ta muốn thống kê xem có bao nhiêu animals tham gia game, chúng ta không thể dùng instance method. Lúc này chúng ta cần khai báo class method:
class Animal:
animals = []
def __init__(self, role, name, color, hp, attack, defence):
self.role = role
self.name = name
self.color = color
self.hp = hp # the animal's health points
self.attack = attack # the animal's attack power
self.defence = defence # the animal's defence power
self.animals.append(self)
def declare(self):
print(f"I am {self.role} {self.name}. \
I am {self.color}. My HP is {self.hp}. \
My attacking power is {self.attack}. \
My defence is {self.defence}.")
@classmethod
def num_of_animals(cls):
return len(cls.animals)
# create instance - cat
cat = Animal('Cat', 'Tom', 'Black', 30, 15, 10)
# create instance - dog
dog = Animal('Dog', 'Scooby Doo', 'White', 35, 8, 10)
print(Animal.num_of_animals())
# prints 2
Xây dựng một phương thức tĩnh @staticmethod giới thiệu về game:
@staticmethod
def intro():
print('Cat vs Dog is an entertaining game in which these two characters, a dog and a cat....')
Tổng kết
Sử dụng các kiểu phương thức tùy vào ý đồ của các lập trình viên. Để hiểu rõ hơn về ba loại phương thức chúng ta cần thực hành nhiều hơn. Mình cũng sẽ cập nhật bài viết này trong thời gian tới.