Python đã là một ngôn ngữ hướng đối tượng kể từ khi nó tồn tại. Do đó, việc tạo và sử dụng các lớp và đối tượng hết sức dễ dàng. Chương này giúp bạn trở thành một chuyên gia trong việc sử dụng hỗ trợ lập trình hướng đối tượng của Python
Nếu bạn chưa có bất kỳ kinh nghiệm nào trước đây về lập trình hướng đối tượng [OO], bạn có thể muốn tham khảo một khóa học giới thiệu về nó hoặc ít nhất là một hướng dẫn nào đó để bạn nắm được các khái niệm cơ bản.
Tuy nhiên, đây là phần giới thiệu nhỏ về Lập trình hướng đối tượng [OOP] để giúp bạn tăng tốc −
Tổng quan về thuật ngữ OOP
Lớp - Một nguyên mẫu do người dùng định nghĩa cho một đối tượng xác định một tập hợp các thuộc tính đặc trưng cho bất kỳ đối tượng nào của lớp. Các thuộc tính là các thành viên dữ liệu [biến lớp và biến thể hiện] và các phương thức, được truy cập thông qua ký hiệu dấu chấm
Biến lớp - Một biến được chia sẻ bởi tất cả các phiên bản của một lớp. Các biến lớp được định nghĩa trong một lớp nhưng bên ngoài bất kỳ phương thức nào của lớp. Các biến lớp không được sử dụng thường xuyên như các biến thể hiện
Thành viên dữ liệu - Một biến lớp hoặc biến thể hiện chứa dữ liệu được liên kết với một lớp và các đối tượng của nó
Quá tải chức năng - Việc gán nhiều hơn một hành vi cho một chức năng cụ thể. Thao tác được thực hiện khác nhau tùy theo loại đối tượng hoặc đối số liên quan
Biến thể hiện - Một biến được định nghĩa bên trong một phương thức và chỉ thuộc về thể hiện hiện tại của một lớp
Kế thừa - Việc chuyển các đặc điểm của một lớp sang các lớp khác có nguồn gốc từ nó
Trường hợp - Một đối tượng riêng lẻ của một lớp nhất định. Một đối tượng obj thuộc về lớp Circle, chẳng hạn, là một thể hiện của lớp Circle
Khởi tạo - Việc tạo một thể hiện của một lớp
Phương thức - Một loại hàm đặc biệt được định nghĩa trong định nghĩa lớp
Đối tượng - Một thể hiện duy nhất của cấu trúc dữ liệu được xác định bởi lớp của nó. Một đối tượng bao gồm cả các thành viên dữ liệu [biến lớp và biến thể hiện] và các phương thức
Nạp chồng toán tử - Việc gán nhiều hơn một hàm cho một toán tử cụ thể
Tạo lớp học
Câu lệnh lớp tạo ra một định nghĩa lớp mới. Tên của lớp ngay sau từ khóa lớp theo sau là dấu hai chấm như sau -
class ClassName: 'Optional class documentation string' class_suite
Lớp này có một chuỗi tài liệu, có thể được truy cập thông qua Tên lớp. __doc__
class_suite bao gồm tất cả các câu lệnh thành phần xác định các thành viên lớp, thuộc tính dữ liệu và hàm
Thí dụ
Sau đây là ví dụ về một lớp Python đơn giản -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary
Biến empCount là một biến lớp có giá trị được chia sẻ giữa tất cả các phiên bản của lớp này. Điều này có thể được truy cập như nhân viên. empCount từ bên trong lớp hoặc bên ngoài lớp
Phương thức đầu tiên __init__[] là một phương thức đặc biệt, được gọi là hàm tạo của lớp hoặc phương thức khởi tạo mà Python gọi khi bạn tạo một thể hiện mới của lớp này
Bạn khai báo các phương thức khác của lớp giống như các hàm bình thường, ngoại trừ đối số đầu tiên cho mỗi phương thức là tự. Python thêm đối số self vào danh sách cho bạn;
Tạo đối tượng sơ thẩm
Để tạo các thể hiện của một lớp, bạn gọi lớp đó bằng tên lớp và truyền vào bất kỳ đối số nào mà phương thức __init__ của nó chấp nhận
"This would create first object of Employee class" emp1 = Employee["Zara", 2000] "This would create second object of Employee class" emp2 = Employee["Manni", 5000]
Truy cập thuộc tính
Bạn truy cập các thuộc tính của đối tượng bằng toán tử dấu chấm với đối tượng. Biến lớp sẽ được truy cập bằng tên lớp như sau -
emp1.displayEmployee[] emp2.displayEmployee[] print "Total Employee %d" % Employee.empCount
Bây giờ, đặt tất cả các khái niệm lại với nhau -
#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee["Zara", 2000] "This would create second object of Employee class" emp2 = Employee["Manni", 5000] emp1.displayEmployee[] emp2.displayEmployee[] print "Total Employee %d" % Employee.empCount
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Bạn có thể thêm, xóa hoặc sửa đổi các thuộc tính của lớp và đối tượng bất kỳ lúc nào −
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
Thay vì sử dụng các câu lệnh thông thường để truy cập các thuộc tính, bạn có thể sử dụng các hàm sau –
getattr[obj, name[, default]] − để truy cập thuộc tính của đối tượng
hasattr[obj,name] − để kiểm tra xem một thuộc tính có tồn tại hay không
setattr[obj,name,value] − để thiết lập một thuộc tính. Nếu thuộc tính không tồn tại, thì nó sẽ được tạo
delattr[obj, name] − để xóa một thuộc tính
hasattr[emp1, 'age'] # Returns true if 'age' attribute exists getattr[emp1, 'age'] # Returns value of 'age' attribute setattr[emp1, 'age', 8] # Set attribute 'age' at 8 delattr[empl, 'age'] # Delete attribute 'age'
Thuộc tính lớp tích hợp
Mỗi lớp Python tuân theo các thuộc tính dựng sẵn và chúng có thể được truy cập bằng cách sử dụng toán tử dấu chấm giống như bất kỳ thuộc tính nào khác -
__dict__ − Từ điển chứa không gian tên của lớp
__doc__ − Chuỗi tài liệu lớp hoặc không có, nếu không xác định
__name__ − Tên lớp
__module__ − Tên mô-đun trong đó lớp được định nghĩa. Thuộc tính này là "__main__" trong chế độ tương tác
__bases__ − Một bộ trống có thể chứa các lớp cơ sở, theo thứ tự xuất hiện của chúng trong danh sách lớp cơ sở
Đối với lớp trên, chúng ta hãy thử truy cập tất cả các thuộc tính này -
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
Employee.__doc__: Common base class for all employees Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: [] Employee.__dict__: {'__module__': '__main__', 'displayCount': , 'empCount': 2, 'displayEmployee': , '__doc__': 'Common base class for all employees', '__init__': }
Phá hủy đồ vật [Thu gom rác]
Python tự động xóa các đối tượng không cần thiết [kiểu dựng sẵn hoặc thể hiện lớp] để giải phóng không gian bộ nhớ. Quá trình Python thu hồi định kỳ các khối bộ nhớ không còn được sử dụng nữa được gọi là Bộ sưu tập rác
Trình thu gom rác của Python chạy trong khi thực thi chương trình và được kích hoạt khi số tham chiếu của đối tượng bằng 0. Số lượng tham chiếu của một đối tượng thay đổi khi số lượng bí danh trỏ tới nó thay đổi
Số lượng tham chiếu của một đối tượng tăng lên khi nó được gán một tên mới hoặc được đặt trong một vùng chứa [danh sách, bộ hoặc từ điển]. Số lượng tham chiếu của đối tượng giảm khi đối tượng bị xóa bằng del, tham chiếu của đối tượng được gán lại hoặc tham chiếu của đối tượng nằm ngoài phạm vi. Khi số lượng tham chiếu của một đối tượng bằng 0, Python sẽ tự động thu thập nó
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary0
Thông thường, bạn sẽ không nhận thấy khi trình thu gom rác phá hủy một phiên bản mồ côi và lấy lại không gian của nó. Nhưng một lớp có thể triển khai phương thức đặc biệt __del__[], được gọi là hàm hủy, được gọi khi thể hiện sắp bị hủy. Phương pháp này có thể được sử dụng để dọn sạch mọi tài nguyên không phải bộ nhớ được sử dụng bởi một phiên bản
Thí dụ
Hàm hủy __del__[] này in tên lớp của một thể hiện sắp bị hủy -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary1
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary2
Lưu ý - Tốt nhất, bạn nên định nghĩa các lớp của mình trong tệp riêng biệt, sau đó bạn nên nhập chúng vào tệp chương trình chính của mình bằng cách sử dụng câu lệnh nhập
Kế thừa lớp
Thay vì bắt đầu từ đầu, bạn có thể tạo một lớp bằng cách lấy nó từ một lớp có sẵn bằng cách liệt kê lớp cha trong dấu ngoặc đơn sau tên lớp mới
Lớp con kế thừa các thuộc tính của lớp cha và bạn có thể sử dụng các thuộc tính đó như thể chúng được định nghĩa trong lớp con. Một lớp con cũng có thể ghi đè các thành viên dữ liệu và phương thức từ lớp cha
cú pháp
Các lớp dẫn xuất được khai báo giống như lớp cha của chúng;
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary3
Thí dụ
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary4
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary5
Tương tự như vậy, bạn có thể điều khiển một lớp từ nhiều lớp cha như sau -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary6
Bạn có thể sử dụng hàm issubclass[] hoặc isinstance[] để kiểm tra mối quan hệ của hai lớp và thể hiện
Hàm boolean issubclass[sub, sup] trả về true nếu phân lớp con đã cho sub thực sự là một phân lớp của siêu lớp sup
Hàm boolean isinstance[obj, Class] trả về true nếu obj là một thể hiện của lớp Lớp hoặc là một thể hiện của một lớp con của Lớp
Phương thức ghi đè
Bạn luôn có thể ghi đè các phương thức của lớp cha. Một lý do để ghi đè các phương thức của cha mẹ là vì bạn có thể muốn chức năng đặc biệt hoặc khác trong lớp con của mình
Thí dụ
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary7
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary8
Phương pháp nạp chồng cơ sở
Bảng sau liệt kê một số chức năng chung mà bạn có thể ghi đè trong các lớp của riêng mình -
__init__ [ tự [,args. ] ]
Constructor [với bất kỳ đối số tùy chọn nào]
cuộc gọi mẫu. obj = className[args]
2__del__[ tự ]
Destructor, xóa một đối tượng
cuộc gọi mẫu. xóa đối tượng
3__repr__[ tự ]
Biểu diễn chuỗi có thể đánh giá được
cuộc gọi mẫu. đại diện [obj]
4__str__[ tự ]
Biểu diễn chuỗi có thể in
cuộc gọi mẫu. str[obj]
5__cmp__ [ tự, x ]
đối tượng so sánh
cuộc gọi mẫu. cmp[obj, x]
Toán tử quá tải
Giả sử bạn đã tạo một lớp Vector để biểu diễn các vectơ hai chiều, điều gì sẽ xảy ra khi bạn sử dụng toán tử cộng để cộng chúng?
Tuy nhiên, bạn có thể định nghĩa phương thức __add__ trong lớp của mình để thực hiện phép cộng vectơ và sau đó toán tử cộng sẽ hoạt động như mong đợi -
Thí dụ
class Employee: 'Common base class for all employees' empCount = 0 def __init__[self, name, salary]: self.name = name self.salary = salary Employee.empCount += 1 def displayCount[self]: print "Total Employee %d" % Employee.empCount def displayEmployee[self]: print "Name : ", self.name, ", Salary: ", self.salary9
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
"This would create first object of Employee class" emp1 = Employee["Zara", 2000] "This would create second object of Employee class" emp2 = Employee["Manni", 5000]0
Ẩn dữ liệu
Các thuộc tính của một đối tượng có thể hiển thị hoặc không hiển thị bên ngoài định nghĩa lớp. Bạn cần đặt tên cho các thuộc tính có tiền tố gạch dưới kép và những thuộc tính đó sẽ không hiển thị trực tiếp với người ngoài
Thí dụ
"This would create first object of Employee class" emp1 = Employee["Zara", 2000] "This would create second object of Employee class" emp2 = Employee["Manni", 5000]1
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
"This would create first object of Employee class" emp1 = Employee["Zara", 2000] "This would create second object of Employee class" emp2 = Employee["Manni", 5000]2
Python bảo vệ các thành viên đó bằng cách thay đổi tên bên trong để bao gồm tên lớp. Bạn có thể truy cập các thuộc tính như đối tượng. _className__attrName. Nếu bạn thay thế dòng cuối cùng của mình như sau, thì nó phù hợp với bạn -