Tin tức và phân tích của tất cả các thiết bị di động

__init__ trong Python là gì? [With Examples]

Bạn muốn bắt đầu thiết kế hướng đối tượng bằng Python? Hãy bắt đầu ngay hôm nay bằng cách học phương pháp __init__ của Python.

Trong hướng dẫn này, chúng ta sẽ đề cập đến kiến ​​thức cơ bản về các lớp và đối tượng Python, sau đó chuyển sang tìm hiểu về phương thức __init__.

Đến cuối hướng dẫn này, bạn sẽ có thể trả lời các câu hỏi sau:

  • Biến thể hiện hoặc thuộc tính thể hiện là gì?
  • Phương thức init giúp khởi tạo các thuộc tính cá thể như thế nào?
  • Làm cách nào chúng ta có thể đặt giá trị mặc định cho thuộc tính?
  • Làm cách nào chúng ta có thể sử dụng các phương thức lớp làm hàm tạo để tạo đối tượng?

Hãy bắt đầu.

Các lớp và đối tượng Python

Các lớp là nền tảng của lập trình hướng đối tượng trong Python. Chúng ta có thể tạo một lớp và định nghĩa các thuộc tính cũng như phương thức để liên kết dữ liệu và các hàm liên quan với nhau.

Sau khi lớp được tạo, chúng ta có thể sử dụng nó làm bản thiết kế (hoặc mẫu) để tạo các đối tượng (thể hiện).

👩‍🏫Thời gian lấy mẫu! Hãy tạo một lớp Nhân viên trong đó mỗi đối tượng của lớp này có các thuộc tính sau:

  • full_name: tên đầy đủ của nhân viên theo dạng họ và tên
  • emp_id: ID nhân viên
  • bộ phận: bộ phận họ thuộc về
  • kinh nghiệm: số năm kinh nghiệm họ có

Nó có nghĩa là gì? 🤔

Mỗi nhân viên riêng lẻ sẽ là một thể hiện hoặc đối tượng của lớp Nhân viên. Mỗi đối tượng sẽ có giá trị riêng cho full_name, emp_id, bộ phận và trải nghiệm.

Các thuộc tính này còn được gọi là biến mẫu và chúng ta sẽ sử dụng thuật ngữ thuộc tính và biến mẫu thay thế cho nhau.

Chúng ta sẽ chuyển sang việc thêm thuộc tính trong giây lát. Hiện tại, chúng ta tạo lớp Nhân viên như sau:

class Employee:
    pass

Việc sử dụng pass (làm placeholder) giúp chúng ta tránh được lỗi khi chạy script.

Mặc dù phiên bản hiện tại của lớp Nhân viên không giúp ích nhiều nhưng đây vẫn là một lớp hợp lệ. Vì vậy chúng ta có thể tạo các đối tượng của lớp Nhân viên:

employee_1 = Employee()

print(employee_1)
#Output: <__main__.Employee object at 0x00FEE7F0>

Chúng ta cũng có thể thêm thuộc tính và khởi tạo chúng với giá trị như hình:

employee_1.full_name="Amy Bell"
employee_1.department="HR"

Tuy nhiên, cách tiếp cận này để thêm các thuộc tính cá thể vừa không hiệu quả vừa dễ xảy ra lỗi. Nó cũng không cho phép lớp này được sử dụng làm mẫu để tạo đối tượng. Đây là lúc phương thức __init__ phát huy tác dụng.

Hiểu vai trò của phương thức __init__ trong lớp Python

Chúng ta có thể khởi tạo các biến thể hiện khi khởi tạo một đối tượng và phương thức __init__ giúp chúng ta thực hiện điều đó. Phương thức __init__ được gọi mỗi khi một đối tượng lớp mới được tạo để khởi tạo các giá trị biến thể hiện.

Nếu bạn đã lập trình bằng ngôn ngữ như C++, bạn sẽ thấy phương thức __init__ hoạt động tương tự như hàm tạo.

Xác định phương thức __init__

Hãy thêm phương thức __init__ vào lớp Nhân viên:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience

Tham số self đề cập đến một thể hiện của lớp và self.attribute khởi tạo thuộc tính thể hiện thành giá trị ở bên phải.

Bây giờ chúng ta có thể tạo các đối tượng như thế này:

employee_2 = Employee('Bella Joy','M007','Marketing',3)
print(employee_2)
# Output: <__main__.Employee object at 0x017F88B0>

Khi in các đối tượng nhân viên, chúng ta không nhận được bất kỳ thông tin hữu ích nào ngoài lớp mà chúng thuộc về. Hãy thêm phương thức __repr__ để xác định một chuỗi đại diện cho lớp:

 def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Thêm __repr__ vào lớp Nhân viên, chúng ta có:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Bây giờ các đối tượng worker có một chuỗi biểu diễn hữu ích:

print(employee_2)
# Output: Bella Joy,M007 from Marketing with 3 years of experience.

Một số quy ước

Trước khi chúng tôi tiến hành, đây là một số lưu ý:

  • Chúng tôi đã sử dụng self làm tham số đầu tiên trong phương thức __init__ để chỉ chính thể hiện của lớp và chúng tôi đã sử dụng self.attribute_name để khởi tạo các thuộc tính khác nhau. Sử dụng self là quy ước được ưu tiên (bạn có thể sử dụng bất kỳ tên nào khác).
  • Khi xác định phương thức __init__, chúng tôi đặt tên tham số trong định nghĩa __init__ để khớp với tên thuộc tính. Điều này cải thiện khả năng đọc.

Cách thêm giá trị mặc định cho thuộc tính

Trong ví dụ chúng ta đã viết mã cho đến nay, tất cả các thuộc tính đều bắt buộc. Điều này có nghĩa là việc tạo đối tượng sẽ chỉ thành công nếu chúng ta chuyển giá trị cho tất cả các trường cho hàm tạo.

Hãy thử tạo một thể hiện của đối tượng lớp Nhân viên mà không chuyển giá trị của thuộc tính trải nghiệm:

employee_3 = Employee('Jake Lee','E001','Engineering')

Bạn sẽ nhận được lỗi sau:

Traceback (most recent call last):
  File "main.py", line 22, in <module>
    employee_3 = Employee('Jake Lee','E001','Engineering')
TypeError: __init__() missing 1 required positional argument: 'experience'

Nhưng nếu bạn muốn một số thuộc tính là tùy chọn, bạn có thể làm như vậy bằng cách cung cấp các giá trị mặc định cho các thuộc tính đó khi xác định phương thức __init__.

Ở đây chúng tôi đưa ra giá trị mặc định 0 cho thuộc tính trải nghiệm:

class Employee:
    def __init__(self, full_name,emp_id,department,experience=0):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Đối tượng nhan viên_3 được tạo không có giá trị cho thuộc tính trải nghiệm; giá trị mặc định được sử dụng cho trải nghiệm 0.

employee_3 = Employee('Jake Lee','E001','Engineering')
print(employee_3.experience)
# Output: 0

Các hàm tạo lớp thay thế sử dụng các phương thức lớp

Cho đến nay chúng ta chỉ mới biết cách xác định phương thức __init__ và đặt giá trị thuộc tính mặc định khi cần. Chúng tôi cũng biết rằng chúng tôi cần chuyển các giá trị của các thuộc tính bắt buộc trong hàm tạo.

Tuy nhiên, đôi khi giá trị của các biến thể hiện (hoặc thuộc tính) này có thể có sẵn trong cấu trúc dữ liệu khác, chẳng hạn như bộ tuple, từ điển hoặc chuỗi JSON.

Vì vậy, những gì chúng ta đang làm gì?

Hãy lấy một ví dụ. Giả sử chúng ta có các giá trị của một biến instance trong từ điển python:

dict_fanny = {'name':'Fanny Walker','id':'H203','dept':'HR','exp':2}

Chúng ta có thể chạm vào từ điển và nhận được tất cả các thuộc tính như thế này:

name = dict_fanny['name']
id = dict_fanny['id']
dept = dict_fanny['dept']
exp = dict_fanny['exp']

Sau đó, bạn có thể tạo một đối tượng bằng cách chuyển các giá trị này cho hàm tạo của lớp:

employee_4 = Employee(name, id, dept, exp)
print(employee_4)
# Output: Fanny Walker,H203 from HR with 2 years of experience.

Hãy nhớ rằng: bạn phải làm điều này cho mọi đối tượng mới mà bạn tạo. Cách tiếp cận này không hiệu quả và chúng tôi chắc chắn có thể làm tốt hơn. Nhưng bằng cách nào?

Trong Python, chúng ta có thể sử dụng các phương thức lớp làm hàm tạo để tạo các đối tượng lớp. Để tạo một phương thức lớp, chúng ta sử dụng trình trang trí @classmethod.

Hãy xác định một phương thức phân tích từ điển, truy xuất các giá trị của các biến thể hiện và sử dụng chúng để xây dựng các đối tượng nhân viên.

    @classmethod
    def from_dict(cls,data_dict):
        full_name = data_dict['name']
        emp_id = data_dict['id']
        department = data_dict['dept']
        experience = data_dict['exp']
        return cls(full_name, emp_id, department, experience)

Khi cần tạo đối tượng bằng dữ liệu từ từ điển, chúng ta có thể sử dụng phương thức lớp from_dict().

💡 Lưu ý sử dụng cls trong phương thức lớp thay vì self. Giống như chúng ta sử dụng self để chỉ một thể hiện, cls được dùng để chỉ một lớp. Ngoài ra, các phương thức lớp được liên kết với lớp chứ không phải với các đối tượng.

Vì vậy, khi chúng ta gọi phương thức from_dict() để tạo đối tượng, chúng ta gọi nó trong lớp Nhân viên:

emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# Output: Tia Bell,S270 from Sales with 3 years of experience.

Bây giờ, nếu chúng ta có một từ điển cho mỗi n nhân viên, chúng ta có thể sử dụng phương thức lớp from_dict() làm hàm tạo để khởi tạo các đối tượng – mà không cần phải truy xuất các giá trị biến ngay lập tức từ từ điển.

📝 Lưu ý về biến lớp

Ở đây chúng ta đã định nghĩa một phương thức lớp được liên kết với lớp đó chứ không phải với các cá thể riêng lẻ. Giống như các phương thức lớp, chúng ta cũng có thể có các biến lớp.

Giống như các phương thức lớp, các biến lớp được liên kết với lớp chứ không phải với thể hiện. Khi một thuộc tính nhận một giá trị không đổi cho tất cả các phiên bản của một lớp, chúng ta có thể coi việc định nghĩa chúng là các biến của lớp.

Các câu hỏi thường gặp

1. Tại sao bạn cần phương thức __init__ trong Python?

Phương thức __init__ trong định nghĩa lớp cho phép chúng ta khởi tạo các thuộc tính hoặc biến thể hiện của tất cả các thể hiện của lớp. Phương thức __init__ được gọi mỗi khi một phiên bản lớp mới được tạo.

2. Bạn có thể có nhiều phương thức __init__ trong lớp python không?

Mục đích của việc có nhiều phương thức __init__ trong một lớp Python là cung cấp nhiều hàm tạo để khởi tạo các đối tượng. Nhưng bạn không thể định nghĩa nhiều phương thức __init__. Nếu bạn xác định nhiều phương thức __init__ thì phương thức triển khai thứ hai và mới nhất sẽ thay thế phương thức đầu tiên. Tuy nhiên, bạn có thể sử dụng trình trang trí @classmethod để xác định các phương thức lớp có thể được sử dụng làm hàm tạo để khởi tạo các đối tượng.

3. Điều gì xảy ra nếu bạn không định nghĩa phương thức __init__ trong một lớp?

Nếu bạn không xác định phương thức __init__, bạn vẫn có thể khởi tạo đối tượng. Tuy nhiên, bạn sẽ phải thêm các biến instance theo cách thủ công và gán giá trị cho từng biến đó. Bạn sẽ không thể truyền các giá trị biến thể hiện trong hàm tạo. Điều này không chỉ dễ xảy ra lỗi mà còn phá vỡ mục đích sử dụng một lớp làm bản thiết kế để từ đó chúng ta có thể khởi tạo các đối tượng.

4. Bạn có thể có các giá trị đối số mặc định trong phương thức __init__ không?

Có, bạn có thể chỉ định giá trị mặc định cho một hoặc nhiều thuộc tính khi xác định phương thức __init__. Việc cung cấp các giá trị mặc định giúp làm cho các thuộc tính này trở thành tùy chọn trong hàm tạo. Các thuộc tính lấy giá trị mặc định khi bạn không truyền giá trị cho các thuộc tính đó trong hàm tạo.

5. Bạn có thể sửa đổi các thuộc tính bên ngoài phương thức __init__ không?

Có, bạn luôn có thể cập nhật giá trị thuộc tính bên ngoài phương thức __init__. Bạn cũng có thể tự động thêm các thuộc tính mới vào một phiên bản sau khi nó được tạo.

Ứng dụng

Trong hướng dẫn này, chúng ta đã học cách sử dụng phương thức __init__ để khởi tạo giá trị của các biến thực thể. Mặc dù đơn giản nhưng nó có thể lặp đi lặp lại – đặc biệt khi bạn có nhiều thuộc tính.

Nếu bạn quan tâm, bạn có thể tham khảo mô-đun dataclasses. Bằng Python 3.7 và sau này, bạn có thể sử dụng mô-đun lớp dữ liệu tích hợp sẵn để tạo các lớp dữ liệu chứa dữ liệu. Ngoài việc triển khai mặc định __init__ và các phương thức thường được sử dụng khác; đi kèm với nhiều tính năng thú vị như gợi ý loại, mặc định phức tạp và tối ưu hóa.

Sau đó tìm hiểu thêm về if __name__==’__main__’ trong Python.

Mục lục