Hàm self trong Python

Trong Python, self không phải là một hàm mà là một tham số đặc biệt được sử dụng trong các phương thức của lớp để tham chiếu đến chính đối tượng hiện tại. Mặc dù self không phải là từ khóa bắt buộc trong Python, nhưng nó đã trở thành tiêu chuẩn và thông lệ khi định nghĩa các phương thức trong lớp.

Tham số self được dùng để truy cập các thuộc tính và phương thức của đối tượng hiện tại và phân biệt chúng với các biến cục bộ hoặc các tham số khác. Khi một đối tượng được tạo từ một lớp, các phương thức của nó cần tham chiếu đến các thuộc tính và phương thức riêng của đối tượng đó, và đây chính là vai trò của self.

1. Cấu Trúc self trong Phương Thức

Trong Python, khi bạn định nghĩa một phương thức trong lớp, tham số đầu tiên thường là self. Tham số này tự động được truyền vào khi bạn gọi phương thức thông qua đối tượng.

Ví dụ cơ bản về self trong lớp:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        return f"Hello, my name is {self.name} and I am {self.age} years old."

# Tạo một đối tượng của lớp Person
person = Person("Anh", 25)

# Gọi phương thức greet
print(person.greet())
# Output: Hello, my name is Anh and I am 25 years old.

Trong ví dụ trên:

  • self.nameself.age: Những dòng này gán giá trị của tham số được truyền vào (nameage) cho các thuộc tính của đối tượng (self.nameself.age). Việc sử dụng self đảm bảo rằng các thuộc tính này được lưu trữ riêng biệt cho mỗi đối tượng cụ thể.
  • self trong phương thức greet(): Phương thức này sử dụng self.nameself.age để truy cập và trả về các thuộc tính của đối tượng hiện tại.

2. Tại Sao Cần Sử Dụng self?

Lý do quan trọng nhất để sử dụng self là để phân biệt giữa các biến cục bộ và các thuộc tính của đối tượng. Nó cho phép mỗi đối tượng của một lớp có thể giữ các giá trị riêng biệt của các thuộc tính, đồng thời cung cấp khả năng truy cập các phương thức và thuộc tính của chính đối tượng đó.

Ví dụ:

class Person:
    def __init__(self, name):
        self.name = name  # Sử dụng self để tham chiếu đến thuộc tính của đối tượng

    def greet(self):
        name = "Người lạ"  # Biến cục bộ chỉ tồn tại trong phương thức
        return f"Hello, {self.name}"  # Sử dụng self.name để truy cập thuộc tính của đối tượng

person = Person("Anh")
print(person.greet())
# Output: Hello, Anh

Ở đây, biến cục bộ name = "Người lạ" không ảnh hưởng đến thuộc tính self.name của đối tượng, bởi vì self.name chỉ ra rằng chúng ta đang tham chiếu đến thuộc tính của đối tượng hiện tại.

3. self Làm Việc Như Thế Nào Trong Các Phương Thức?

Khi bạn gọi một phương thức trên một đối tượng, Python tự động truyền đối tượng hiện tại (đối tượng đã gọi phương thức) làm tham số đầu tiên cho phương thức đó. Đây là lý do tại sao bạn phải sử dụng self để nhận tham chiếu đến đối tượng hiện tại.

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        return f"{self.name} is barking!"

dog = Dog("Bobby")
print(dog.bark())  # Bobby is barking!

Trong đoạn code trên, khi bạn gọi dog.bark(), Python thực hiện tương tự như sau:

Dog.bark(dog)

Python ngầm truyền đối tượng dog như là tham số đầu tiên của phương thức bark(), đó là lý do tại sao bạn cần phải có self để nhận tham chiếu đến đối tượng dog.

4. self Trong Các Phương Thức Tĩnh và Lớp

Có những trường hợp bạn không cần đến self. Ví dụ, trong phương thức tĩnh (staticmethod) hoặc phương thức lớp (classmethod), bạn sẽ không sử dụng self.

Phương Thức Tĩnh (@staticmethod)

Phương thức tĩnh không nhận tham chiếu đến đối tượng hiện tại, và không cần self. Nó hoạt động như một hàm bình thường được đặt bên trong lớp.

class Math:
    @staticmethod
    def add(a, b):
        return a + b

print(Math.add(3, 4))  # Output: 7

Phương Thức Lớp (@classmethod)

Phương thức lớp nhận tham số cls thay vì self, trong đó cls là tham chiếu đến chính lớp thay vì đối tượng.

class Animal:
    species = "Mammal"

    @classmethod
    def get_species(cls):
        return cls.species

print(Animal.get_species())  # Output: Mammal

Trong ví dụ này, cls là tham chiếu đến lớp Animal, và không phải là một đối tượng cụ thể.

5. Tùy Chọn Không Sử Dụng Tên self

Bạn không bắt buộc phải sử dụng từ khóa self. Python chỉ yêu cầu tham số đầu tiên trong phương thức phải tham chiếu đến đối tượng, nhưng bạn có thể đặt tên tham số này thành bất cứ điều gì bạn muốn.

class Person:
    def __init__(this, name):
        this.name = name

    def greet(this):
        return f"Hello, my name is {this.name}"

person = Person("Anh")
print(person.greet())
# Output: Hello, my name is Anh

Tuy nhiên, sử dụng tên khác thay vì self sẽ làm mã của bạn khó đọc hơn và không theo chuẩn Python.

6. Kết Luận

Tham số self là một khái niệm cốt lõi trong lập trình hướng đối tượng của Python. Nó cung cấp một cách để các phương thức truy cập và thao tác với các thuộc tính cũng như phương thức của đối tượng hiện tại. Dù bạn có thể sử dụng bất kỳ tên nào cho tham số này, việc tuân theo chuẩn và sử dụng self sẽ giúp mã của bạn dễ hiểu và dễ duy trì hơn.