Sitelet https://www.datacamp.com/vi/tutorial/python-oop-tutorial
Chuyển đến nội dung chính

Lập trình hướng đối tượng trong Python: Hướng dẫn hoàn chỉnh

Học các kiến thức cơ bản về lập trình hướng đối tượng trong Python: lớp, đối tượng, thuộc tính và phương thức được giải thích từng bước kèm ví dụ mã.
Đã cập nhật 5 thg 10, 2026  · 12 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Lập trình hướng đối tượng (OOP) là một khái niệm được sử dụng rộng rãi để viết ứng dụng. Với tư cách là một nhà khoa học dữ liệu, bạn nên có khả năng viết các ứng dụng để xử lý dữ liệu của mình, cùng nhiều việc khác.

Trong hướng dẫn này, tôi trình bày các kiến thức cơ bản về lập trình hướng đối tượng trong Python. Bạn sẽ học cách tạo một lớp và khởi tạo đối tượng, cách định nghĩa phương thức và truyền đối số cho nó, cũng như cách thêm thuộc tính cho một lớp.

Tóm tắt nhanh

  • OOP tổ chức mã xoay quanh lớp (bản thiết kế) và đối tượng (các thể hiện của bản thiết kế đó)

  • Định nghĩa một lớp với từ khóa class và khởi tạo thuộc tính bên trong __init__(self)

  • Phương thức thực thể thao tác trên dữ liệu của đối tượng thông qua self và được gọi bằng dấu chấm: my_object.method()

  • Python hỗ trợ cả bốn trụ cột OOP: đóng gói, kế thừa, đa hình và trừu tượng

  • OOP thúc đẩy tái sử dụng mã để tạo nhiều đối tượng từ một mẫu lớp duy nhất

OOP là gì?

Lập trình hướng đối tượng (OOP) dựa trên mô hình lập trình mệnh lệnh, mô hình sử dụng các câu lệnh để thay đổi trạng thái của chương trình. “Mệnh lệnh” nghĩa là tập trung mô tả cách chương trình nên vận hành. Ví dụ về các ngôn ngữ lập trình mệnh lệnh gồm C, C++, Java, Go, Ruby và Python.

Điều này trái ngược với lập trình khai báo, tập trung vào việc chương trình nên đạt được điều gì, mà không chỉ định cách thực hiện (ví dụ: SQL, XQuery). Để so sánh các mô hình, xem hướng dẫn lập trình hàm so với OOP của chúng tôi.

OOP sử dụng khái niệm đối tượng và lớp. Có thể xem lớp như một “bản thiết kế” cho các đối tượng. Chúng có thể có

  • Thuộc tính: đặc điểm mà chúng sở hữu
  • Phương thức: hành động mà chúng thực hiện

OOP có một vài ưu điểm nổi bật so với các mẫu thiết kế khác. Phát triển thường nhanh hơn và rẻ hơn, và cách tiếp cận theo mô-đun giúp phần mềm dễ bảo trì. Điều này dẫn đến phần mềm chất lượng cao hơn, đồng thời dễ mở rộng với các phương thức và thuộc tính mới.

Tuy nhiên, đường cong học tập dài hơn. Các khái niệm cốt lõi đòi hỏi đầu tư ban đầu để hiểu thấu đáo. Về mặt tính toán, phần mềm OOP chậm hơn và dùng nhiều bộ nhớ hơn vì phải viết nhiều dòng mã hơn.

Bốn trụ cột của OOP

Vượt ra ngoài lớp và phương thức, OOP dựa trên bốn trụ cột mà đến giờ tôi mới chỉ lướt qua. Mỗi trụ cột xứng đáng có một bài đào sâu riêng, nhưng dưới đây là phần tổng quan nhanh kèm liên kết đến các hướng dẫn chuyên sâu.

Trụ cộtÝ nghĩaTìm hiểu thêm
Đóng góiGói dữ liệu và phương thức cùng nhau, kiểm soát truy cập bằng quy ước đặt tên (_private, __name_mangled)Đóng gói trong Python
Kế thừaTạo lớp con tái sử dụng và mở rộng hành vi của lớp chaKế thừa trong Python
Đa hìnhCác lớp khác nhau chia sẻ cùng một giao diện, để mã có thể làm việc hoán đổi với các đối tượngKhóa học OOP trong Python
Trừu tượngẨn sự phức tạp sau một giao diện gọn gàng bằng các lớp cơ sở trừu tượngLớp trừu tượng trong Python

Ví dụ về OOP

Một ví dụ về lớp là lớp Dog. Đừng nghĩ về một chú chó cụ thể hay con chó của bạn. Chúng ta đang mô tả một con chó là gì và có thể làm gì, nói chung. Chó thường có name và age; đây là các thuộc tính thực thể. Chó cũng có thể bark; đây là một phương thức.

Khi bạn nói về một con chó cụ thể, trong lập trình bạn sẽ có một đối tượng: đối tượng là một thể hiện của lớp. Đây là nguyên tắc cơ bản mà lập trình hướng đối tượng dựa vào. Vậy nên con chó Ozzy của tôi, chẳng hạn, thuộc lớp Dog. Các thuộc tính của nó là name = 'Ozzy' và age = '2'. Một con chó khác sẽ có các thuộc tính khác.

OOP trong Python

Python là một trong những ngôn ngữ phổ biến nhất để học và áp dụng OOP. Bên dưới, tôi đề cập đến những gì khiến Python phù hợp với mã hướng đối tượng và đi qua cú pháp cốt lõi.

Python có hướng đối tượng không?

Python là một ngôn ngữ lập trình tuyệt vời hỗ trợ OOP. Bạn sẽ dùng nó để định nghĩa một lớp với các thuộc tính và phương thức, rồi gọi chúng.

Lợi thế chính của Python so với các ngôn ngữ khác như Java, C++ hay R là nó là ngôn ngữ động với các kiểu dữ liệu cấp cao. Điều này có nghĩa lập trình viên không cần khai báo kiểu của biến và đối số, giúp phát triển nhanh hơn nhiều và mã dễ đọc hơn so với Java hay C++.

Nếu bạn mới bắt đầu với Python, nhớ xem khóa học Giới thiệu về Python của chúng tôi.

Cách tạo một lớp

Để định nghĩa một lớp trong Python, bạn có thể dùng từ khóa class, theo sau là tên lớp và dấu hai chấm.

Bên trong lớp, thường định nghĩa một phương thức __init__ (một dunder method) với def. Đây là bộ khởi tạo mà bạn có thể dùng sau đó để khởi tạo đối tượng. Nó tương tự constructor trong Java.

__init__ được gọi tự động khi bạn tạo một đối tượng mới. Nó nhận một đối số: self, tham chiếu đến chính đối tượng đó.

Bên trong phương thức, từ khóa pass tạm thời được dùng vì Python mong đợi bạn gõ gì đó ở đó. Hãy nhớ thụt đầu dòng cho đúng!

class Dog:

    def __init__(self):
        pass

Lưu ý: self trong Python tương đương với this trong C++ hoặc Java.

Trong trường hợp này, bạn có một lớp Dog (hầu như trống), nhưng chưa có đối tượng nào. Hãy tạo một đối tượng!

Bắt đầu học Python miễn phí

Khởi tạo đối tượng

Để khởi tạo một đối tượng, gõ tên lớp, theo sau là hai dấu ngoặc. Bạn có thể gán nó cho một biến để theo dõi đối tượng.

ozzy = Dog()

Và in ra:

print(ozzy)
<__main__.Dog object at 0x111f47278>

Thêm thuộc tính cho một lớp

Sau khi in ozzy, bạn thấy rõ đối tượng này là một con chó. Nhưng bạn chưa thêm thuộc tính nào. Hãy đặt cho lớp Dog một tên và tuổi bằng cách viết lại nó:

class Dog:

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

Bạn thấy hàm giờ nhận hai đối số sau self: name và age. Chúng được gán lần lượt cho self.name và self.age. Giờ bạn có thể tạo một đối tượng ozzy mới với tên và tuổi:

ozzy = Dog("Ozzy", 2)

Để truy cập thuộc tính của một đối tượng trong Python, bạn có thể dùng cú pháp dấu chấm. Thực hiện bằng cách gõ tên đối tượng, theo sau là dấu chấm và tên thuộc tính

print(ozzy.name)

print(ozzy.age)
Ozzy
2

Bạn cũng có thể kết hợp thành một câu đầy đủ hơn:

print(ozzy.name + " is " + str(ozzy.age) + " year(s) old.")
Ozzy is 2 year(s) old.

Hàm str() được dùng ở đây để chuyển đổi thuộc tính age, vốn là số nguyên, thành chuỗi, để bạn có thể dùng nó trong hàm print().

Định nghĩa phương thức trong một lớp

Bây giờ bạn có lớp Dog, nó có tên và tuổi để bạn theo dõi, nhưng thực ra nó chưa làm gì cả. Đây là lúc các phương thức thực thể xuất hiện. Bạn có thể viết lại lớp để bao gồm phương thức bark(). Lưu ý cách từ khóa def lại được dùng, cũng như đối số self.

class Dog:

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

    def bark(self):
        print("bark bark!")

Phương thức bark giờ có thể được gọi bằng cú pháp dấu chấm, sau khi khởi tạo đối tượng ozzy mới. Phương thức sẽ in "bark bark!" ra màn hình. Lưu ý dấu ngoặc đơn trong .bark(). Chúng luôn được dùng khi gọi một phương thức. Trường hợp này để trống, vì phương thức bark() không nhận đối số nào.

ozzy = Dog("Ozzy", 2)

ozzy.bark()
bark bark!

Nhớ việc bạn đã in ozzy trước đó chứ? Đoạn mã dưới đây triển khai chức năng này trong lớp Dog với phương thức doginfo(). Sau đó bạn khởi tạo một số đối tượng với các thuộc tính khác nhau và gọi phương thức trên chúng.

class Dog:

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

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

ozzy = Dog("Ozzy", 2)
skippy = Dog("Skippy", 12)
filou = Dog("Filou", 8)

ozzy.doginfo()
skippy.doginfo()
filou.doginfo()
Ozzy is 2 year(s) old.
Skippy is 12 year(s) old.
Filou is 8 year(s) old.

Như bạn thấy, bạn có thể gọi phương thức doginfo() trên các đối tượng bằng cú pháp dấu chấm. Kết quả giờ phụ thuộc vào đối tượng Dog nào bạn đang gọi phương thức.

Vì chó sẽ già đi, sẽ thật hay nếu bạn có thể điều chỉnh tuổi của chúng cho phù hợp. Ozzy vừa tròn 3 tuổi, vậy hãy đổi tuổi của nó.

ozzy.age = 3

print(ozzy.age)
3

Đơn giản như gán giá trị mới cho thuộc tính. Bạn cũng có thể triển khai điều này thành một phương thức birthday() trong lớp Dog:

class Dog:

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

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

    def birthday(self):
        self.age +=1

ozzy = Dog("Ozzy", 2)

print(ozzy.age)
2
ozzy.birthday()

print(ozzy.age)
3

Giờ bạn không cần tự tay đổi tuổi của chú chó nữa. Bất cứ khi nào đến sinh nhật, bạn chỉ việc gọi phương thức birthday(). 

Truyền đối số cho phương thức

Bạn muốn các chú chó của chúng ta có một bạn đồng hành. Điều này nên là tuỳ chọn vì không phải chú chó nào cũng hòa đồng như nhau.

Xem phương thức setBuddy() bên dưới. Nó nhận self, như thường lệ, và buddy làm đối số. Trong trường hợp này, buddy sẽ là một đối tượng Dog khác. Đặt thuộc tính self.buddy thành buddy, và thuộc tính buddy.buddy thành self.

Điều này có nghĩa mối quan hệ là hai chiều; bạn là bạn của chính bạn mình. Ở đây, Filou sẽ là bạn của Ozzy, đồng nghĩa Ozzy tự động trở thành bạn của Filou.

Bạn cũng có thể đặt các thuộc tính này thủ công thay vì định nghĩa một phương thức, nhưng như vậy sẽ tốn công hơn (viết hai dòng mã thay vì một) mỗi lần bạn muốn đặt bạn đồng hành.

Lưu ý rằng trong Python, bạn không cần chỉ định kiểu của đối số. Nếu là Java thì bắt buộc.

class Dog:

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

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

    def birthday(self):
        self.age +=1

    def setBuddy(self, buddy):
        self.buddy = buddy
        buddy.buddy = self

Giờ bạn có thể gọi phương thức bằng cú pháp dấu chấm và truyền cho nó một đối tượng Dog khác. Ở đây, bạn của Ozzy sẽ là Filou:

ozzy = Dog("Ozzy", 2)
filou = Dog("Filou", 8)

ozzy.setBuddy(filou)

Nếu giờ bạn muốn lấy thông tin về bạn của Ozzy, bạn có thể dùng cú pháp dấu chấm hai lần: Lần đầu để tham chiếu đến bạn của Ozzy, và lần hai để tham chiếu đến thuộc tính của bạn đó.

print(ozzy.buddy.name)
print(ozzy.buddy.age)
Filou
8

Lưu ý rằng điều này cũng có thể làm với Filou.

print(filou.buddy.name)
print(filou.buddy.age)
Ozzy
2

Bạn cũng có thể gọi các phương thức của người bạn. Đối số self được truyền vào doginfo() giờ là ozzy.buddy, tức là filou.

ozzy.buddy.doginfo()
Filou is 8 year(s) old.

Ví dụ OOP trong Python

Một ví dụ nơi lập trình hướng đối tượng trong Python có thể hữu ích là hướng dẫn Python cho Tài chính: Giao dịch thuật toán của chúng tôi. Trong đó, chúng tôi giải thích cách thiết lập một chiến lược giao dịch cho danh mục cổ phiếu.

Chiến lược giao dịch dựa trên đường trung bình động của giá cổ phiếu. Nếu signals['short_mavg'][short_window:] > signals['long_mavg'][short_window:] thỏa mãn, một tín hiệu được tạo ra. Tín hiệu này là dự đoán về biến động giá tương lai của cổ phiếu.

Trong đoạn mã dưới đây, bạn sẽ thấy đầu tiên là khởi tạo, sau đó là tính toán trung bình động và tạo tín hiệu. Vì đây không phải mã hướng đối tượng nên nó chỉ là một khối lớn được thực thi một lần.

Lưu ý chúng ta đang dùng aapl trong ví dụ, đây là mã cổ phiếu của Apple. Nếu bạn muốn làm điều này cho một cổ phiếu khác, bạn sẽ phải viết lại mã.

# Initialize
short_window = 40
long_window = 100
signals = pd.DataFrame(index=aapl.index)
signals['signal'] = 0.0

# Create short simple moving average over the short window
signals['short_mavg'] = aapl['Close'].rolling(window=short_window, min_periods=1, center=False).mean()

# Create long simple moving average over the long window
signals['long_mavg'] = aapl['Close'].rolling(window=long_window, min_periods=1, center=False).mean()

# Create signals
signals['signal'][short_window:] = np.where(signals['short_mavg'][short_window:] > signals['long_mavg'][short_window:], 1.0, 0.0)   

# Generate trading orders
signals['positions'] = signals['signal'].diff()

# Print `signals`
print(signals)

Với cách tiếp cận hướng đối tượng, bạn chỉ cần viết mã khởi tạo và tạo tín hiệu một lần.

Sau đó, bạn có thể tạo một đối tượng mới cho mỗi cổ phiếu bạn muốn tính chiến lược và gọi phương thức generate_signals() trên đó. Lưu ý rằng mã OOP rất giống với mã ở trên, với phần bổ sung là self.

class MovingAverage():

    def __init__(self, symbol, bars, short_window, long_window):
        self.symbol = symbol
        self.bars = bars
        self.short_window = short_window
        self.long_window = long_window

    def generate_signals(self):
        signals = pd.DataFrame(index=self.bars.index)
        signals['signal'] = 0.0

        signals['short_mavg'] = self.bars['Close'].rolling(window=self.short_window, min_periods=1, center=False).mean()
        signals['long_mavg'] = bars['Close'].rolling(window=self.long_window, min_periods=1, center=False).mean()

        signals['signal'][self.short_window:] = np.where(signals['short_mavg'][self.short_window:] > signals['long_mavg'][self.short_window:], 1.0, 0.0)   

        signals['positions'] = signals['signal'].diff()   

        return signals

Giờ bạn chỉ cần khởi tạo một đối tượng với các tham số mong muốn và tạo tín hiệu cho nó.

apple = MovingAverage('aapl', aapl, 40, 100)
print(apple.generate_signals())

Làm điều này cho cổ phiếu khác trở nên rất dễ. Chỉ là khởi tạo một đối tượng mới với mã cổ phiếu khác.

microsoft = MovingAverage('msft', msft, 40, 100)
print(microsoft.generate_signals())

Kết luận

Chúng ta đã đề cập một số khái niệm OOP chính trong Python. Giờ bạn biết cách khai báo lớp và phương thức, khởi tạo đối tượng, thiết lập thuộc tính của chúng và gọi các phương thức thực thể. Các kỹ năng này sẽ hữu ích cho sự nghiệp dữ liệu của bạn trong tương lai.

Để có cách hiện đại hơn khi định nghĩa lớp, hãy xem data classes trong Python, giúp giảm mã lặp. Nếu bạn muốn mở rộng các khái niệm then chốt để tiếp tục làm việc với Python, nhớ xem khóa học Python trung cấp của chúng tôi.

Với OOP, mã của bạn sẽ tăng độ phức tạp khi chương trình lớn dần. Bạn sẽ có các lớp, lớp con, đối tượng, kế thừa, phương thức thực thể và nhiều hơn nữa. Đối với các tình huống kế thừa phức tạp, hãy tìm hiểu về kế thừa đa cấp và super().

Câu hỏi thường gặp về OOP trong Python

Lập trình hướng đối tượng (OOP) là gì?

Lập trình hướng đối tượng là một mô hình lập trình dựa trên khái niệm "đối tượng", có thể chứa dữ liệu và mã thao tác dữ liệu đó. Trong OOP, đối tượng được tạo từ các khuôn mẫu gọi là "lớp", định nghĩa thuộc tính và hành vi của các đối tượng mà chúng tạo ra. OOP cho phép bạn tạo mã có thể tái sử dụng và mô hình hóa các khái niệm trong thế giới thực sát hơn, khiến nó trở thành lựa chọn phổ biến cho nhiều dự án phần mềm.

Lớp và đối tượng trong Python là gì?

Trong Python, lớp là khuôn mẫu để tạo đối tượng. Nó định nghĩa thuộc tính và hành vi của các đối tượng được tạo ra từ nó. Đối tượng là một thể hiện của lớp, được tạo bằng cách gọi lớp như một hàm. Đối tượng chứa dữ liệu và hành vi do lớp định nghĩa, cũng như một danh tính riêng.

Làm thế nào để định nghĩa một lớp trong Python?

Để định nghĩa một lớp trong Python, bạn dùng từ khóa class, theo sau là tên lớp và dấu hai chấm. Phần định nghĩa lớp được thụt đầu dòng, và khối thụt vào đó chứa các thuộc tính và phương thức (hàm) thuộc về lớp.

Làm thế nào để tạo một đối tượng từ lớp trong Python?

Để tạo một đối tượng từ lớp trong Python, bạn gọi lớp như một hàm, truyền vào các đối số cần thiết cho constructor của lớp (phương thức __init__). 

Bốn trụ cột của OOP trong Python là gì?

Bốn trụ cột của lập trình hướng đối tượng gồm: Đóng gói (gói dữ liệu và phương thức cùng nhau đồng thời hạn chế truy cập), Kế thừa (cho phép lớp kế thừa thuộc tính và phương thức từ lớp cha), Đa hình (cho phép xử lý thống nhất các đối tượng thuộc kiểu khác nhau), và Trừu tượng (ẩn chi tiết triển khai phức tạp trong khi phơi bày các tính năng cốt lõi).

Sự khác nhau giữa thuộc tính lớp và thuộc tính thực thể là gì?

Thuộc tính lớp được chia sẻ giữa tất cả các thể hiện của lớp và được định nghĩa trực tiếp trong thân lớp. Thuộc tính thực thể là duy nhất cho mỗi đối tượng và được định nghĩa bên trong phương thức __init__ bằng self. Ví dụ, tất cả chó có thể chia sẻ thuộc tính lớp species, nhưng mỗi con chó có thuộc tính thực thể name riêng.

Chủ đề
Python
Khoa học Dữ liệu
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm