Class trong python

Python là ngôn ngữ hướng đối tượng ngay từ đầu. Bởi vậy, việc tạo ra và sử dụng các lớp và các đối tượng là hết sức dễ dàng. Bài viết này sẽ giúp bạn trở thành một chuyên gia trong việc sử dụng hướng đối tượng hỗ trợ lập trình Python.

Dưới đây là những khái niệm cơ bản nhất:

1. Tổng quan về OOP

  • Class (lớp): Được định nghĩa cho một đối tượng bao gồm một tập các attributes (thuộc tính) đặc trưng cho tất cả các đối tượng của lớp. Attributes gồm: data members và methods được gọi thông qua ký hiệu dấu chấm.
  • Instance: Một hiện thực cụ thể của một lớp, có thể gọi là thực thể
  • object: instance duy nhất chứa cấu trúc dữ liệu được định nghĩa bởi class.(Ví dụ: khai báo lớp HocSinh ta sẽ có object HocSinh, sau đó tạo biến nguyen_van_a = HocSinh() thì có thêm instance nguyen_van_a)
  • Methods: Hàm thực thi
  • Data members: Biến chứa dữ liệu gồm: class variable & instance variable
  • Class variable: Biến dùng chung cho tất cả các đối tượng của lớp, được định nghĩa trong lớp mà không nằm trong methods (hàm thực thi) nào cả. Các biến này không được sử dụng thường xuyên.
  • Instance variable: biến được định nghĩa bên trong methods và chỉ thuộc về các instance (đối tượng thực thể của lớp).
  • Function overloading: method định nghĩa các phép toán nhiều instances tham gia (Ví dụ cộng 2 instances, so sánh lớn hơn nhỏ hơn của 2 instances, ...).
  • Operator overloading: Phép toán cần nhiều method tham gia.
  • Inheritance: Việc chuyển giao các đặc tính của một lớp kế thừa từ lớp khác.
  • Instantiation: Việc tạo ra một instance của một class.

2. Khai báo class

class ClassName(object):
'''Đoạn văn mô tả về class'''

Ví dụ:

class NhanVien(object):
  '''Lớp mô tả cho mọi nhân viên'''
  dem = 0

  def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      NhanVien.dem += 1

  def hien_thi_so_luong(self):
    print "Tổng số nhân viên được tạo: %d" % NhanVien.dem

  def hien_thi_nhan_vien(self):
      print "Tên: ", self.name,  ", Lương: ", self.salary
  • Biến đếm là class variable được dùng chung cho mọi instances, được sử dụng bởi: NhanVien.dem từ trong hay ngoài class đều được
  • Hàm __init __ () là method đặc biệt, gọi là constructor. Hàm này được Python tự động gọi khi một instance mới được tạo ra.
  • Các method khi khai báo thì đều có param (đối số)self, tuy nhiên khi gọi thì bạn không truyền vì Python sẽ tự động truyền instance vào biến self đó

3. Tạo instances

nhan_vien_dev = NhanVien('PhucLC', 5000)
nhan_vien_pm = NhanVien('MinhHT', 500)

Khi đó sẽ gọi hàm init() và truyền instance_1 vào biến self, truyền 'PhucLC' vào biến name, truyền 5000 $ vào biến salary. Khi dùng self.name chính là instance_1.name

4. Truy cập attributes

print "lương của pm", nhan_vien_dev.salary
nhan_vien_pm.hien_thi_nhan_vien()

Có thể tạo mới, sửa, xoá attributes của class hay instance lúc nào cũng được

nhan_vien_pm.age = 28
nhan_vien_pm.girl_friend= 'Không có'
nhan_vien_pm.salary = 10000
del nhan_vien_pm.girl_friend

Ngoài cách thông thường để truy cập các thuộc tính, có thể sử dụng các hàm có sẵn:

  • **getattr(obj, name[, default]): ** Truy cập thuộc tính name của đối tượng obj, nếu obj này không có thuộc tính đó thì trả về giá trị default. Đối số default khi không được truyền sẽ là None.
getattr(nhan_vien_pm, 'age') #trả về 28
getattr(nhan_vien_pm, 'test') #trả về None, do không có thuộc tính 'test'
  • hasattr(obj, name): Trả về True/False, kiểm tra đối tượng obj có thuộc tính name hay không.
hasattr(nhan_vien_pm, 'age') #trả về True
hasattr(nhan_vien_pm, 'test') #trả về False
  • setattr(obj,name,value): gán giá trị cho thuộc tính. Hàm này tương đương với phép: obj.name = value
 setattr(nhan_vien_pm, 'company', 'Framgia')
  • delattr(obj, name): Xóa thuộc tính. Tương đương:
del obj.name

5. Class Inheritance - Kế thừa

Thay vì định nghĩa một class mới hoàn toàn, bạn có thể kế thừa từ lớp (nhiều lớp-đa kế thừa) đã có (gọi là lớp cha). Lớp này sẽ chứa và có thể sử dụng mọi thuộc tính, phương thức của lớp cha đúng như là chúng được định nghĩa tại lớp con.

Lớp con cũng có thể ghi đè (định nghĩa lại) các thuộc tính của lớp cha.

classA(object):
def test(self):
print "hello"

class B(A): pass
b = B()
b.test() # In ra hello

Bạn thấy đấy, lớp B không hề định nghĩa hàm test, nhưng do kế thừa A nên có thể sử dụng hàm test như đã được định nghĩa tại B. Overriding Methods – Ghi đè hàm

classParent: # define parent class
def myMethod(self):
print'parent method'

classChild1(Parent):# define child class
pass

classChild2(Parent):# define child class
def myMethod(self):
print'child override method'

c1 =Child1() # instance of child 1
c1.myMethod() # Gọi method được định nghĩa từ class cha
c2 =Child2() # instance of child 2
c2.myMethod() # Gọi method được định nghĩa lại (override)

6. Thuộc tính ẩn

Thuộc tính có tên bắt đầu bởi 2 dấu gạch dưới "__" là thuộc tính ẩn, không thể truy cập trực tiếp

class Abc(object):
__xyz = 1

a = Abc()
print a.__xyz # báo lỗi không có thuộc tính

Tuy nhiên bạn vẫn có thể truy cập bằng cách:

print a._Abc__xyz # In ra số 1

Lưu ý, đây không phải là thuộc tính riêng (private), mà chỉ giúp hạn chế truy cập (thuộc tính ẩn)

Bạn có thể tìm hiểu thêm về class trong Python tại đây: https://docs.python.org/3.5/tutorial/classes.html