🌱 [Python] 14 - Class, First-Class Functions & self — Khái niệm & ứng dụng

🌱 [Python] 14 - Class, First-Class Functions & self — Khái niệm & ứng dụng

   Trong Python, hàm (function) được xem là first-class citizens — tức là bạn có thể truyền hàm vào như tham số, trả về hàm và gán hàm cho biến. Khi đặt trong bối cảnh lớp (class), bạn sẽ dùng từ khóa self để tham chiếu đến các đối tượng (instance).

    Bài viết này sẽ giải thích rõ khái niệm first-class functions, cách dùng trong Python, và tại sao Python dùng self làm tham số mặc định trong methods của class.

1 - First-Class Functions là gì?

    Python xem mọi thứ đều là đối tượng, bao gồm cả function. Điều này có nghĩa là bạn có thể:

  • Gán hàm cho biến.
  • Truyền hàm vào hàm khác như tham số.
  • Trả về hàm khác từ một hàm.
  • Lưu hàm vào list, dict... như dữ liệu bình thường.

    Khả năng này giúp Python hỗ trợ các mô hình lập trình linh hoạt như callback, higher-order functionsfunctional programming.

Ví dụ: Gán hàm cho biến

def greet(name):
return f"Hello, {name}!"

say_hello = greet # Gán hàm cho biến
print(say_hello("Alice")) # Hello, Alice!

Truyền hàm làm tham số

def executor(func, *args):
return func(*args)

print(executor(greet, "Bob")) # Hello, Bob!

Hàm trả về hàm

def make_multiplier(n):
def multiply(x):
return x * n
return multiply

times3 = make_multiplier(3) # times3 <=> multiply() function
print(times3(7)) # 21

Hàm lưu trong cấu trúc dữ liệu

def add(a, b): return a + b
def sub(a, b): return a - b

operations = {&#x27;add': add, 'sub': sub}
print(operations[&#x27;add'](5, 3)) # 8

💡 Ghi nhớ: Đây chính là nền tảng để hiểu decorator, callback hay closure trong Python.


2 - Class Methods & self — tại sao Python dùng self?

    Khi bạn định nghĩa một method trong class, Python sẽ tự động truyền instance hiện tại vào tham số đầu tiên. Theo quy ước, tham số này được đặt tên là self.

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

def greet(self):
print(f"Hi, I&#x27;m {self.name}")

p = Person("Alice")
p.greet() # Hi, I'm Alice

Giải thích: Khi bạn gọi p.greet(), Python nội bộ sẽ thực hiện Person.greet(p). Vì vậy, self trỏ tới chính đối tượng hiện tại (p).

❓Vì sao không dùng this

    Python khác với Java hay C++ ở chỗ: nó không tự ẩn tham chiếu instance. Việc viết rõ self giúp code dễ đọc hơn và nhất quán giữa các phương thức.

Ví dụ thêm: Truy cập và thay đổi thuộc tính

  1. class Counter:
  2. def __init__(self):
  3. self.value = 0

  4. def increment(self):
  5. self.value += 1
  6. print("Current:", self.value)

  7. c = Counter()
  8. c.increment() # Current: 1
  9. c.increment() # Current: 2

3 - Ví dụ kết hợp Functions + Class

    Khi kết hợp first-class functionsclass, bạn có thể tạo ra các thiết kế rất linh hoạt — đây là nền tảng cho nhiều design pattern trong Python như Strategy, Command, hoặc Observer.


Ví dụ 1: Strategy Pattern

  1. class Calculator:
  2. def __init__(self, operation):
  3. self.operation = operation # lưu function làm "chiến lược" tính toán

  4. def compute(self, a, b):
  5. return self.operation(a, b) # thực thi chiến lược

  6. def add(a, b):
  7. return a + b

  8. def multiply(a, b):
  9. return a * b

  10. calc_add = Calculator(add)
  11. calc_mul = Calculator(multiply)

  12. print(calc_add.compute(2, 3)) # 5
  13. print(calc_mul.compute(2, 3)) # 6

💡 Giải thích:

  • Calculator không cố định cách tính, mà nhận một function làm tham số (operation).
  • Hàm add()multiply() là hai chiến lược (strategies) khác nhau.
  • Khi khởi tạo Calculator(add) hoặc Calculator(multiply), ta có thể “thay não” của class mà không cần thay đổi code bên trong.

🎯 Use case:
Pattern này thường dùng khi bạn muốn một class có thể thay đổi hành vi động — ví dụ:

  • Một robot có thể đổi cách di chuyển (bằng bánh xe, bay, bơi...)
  • Một game có thể thay đổi chiến lược tấn công của quái vật
  • Một hệ thống log có thể đổi cách xử lý output (in ra console, ghi file, gửi HTTP...)


Ví dụ 2: Callback với Class

  1. class Button:
  2. def __init__(self):
  3. self._callback = None

  4. def on_click(self, func):
  5. self._callback = func # gán hàm callback

  6. def click(self):
  7. if self._callback:
  8. self._callback() # gọi hàm khi click

  9. def say_hi():
  10. print("Hi there!")

  11. btn = Button()
  12. btn.on_click(say_hi)
  13. btn.click() # Hi there!

💡 Giải thích:

  • Button hoạt động như một đối tượng giao diện (GUI element).
  • on_click() cho phép người dùng truyền vào function callback sẽ được gọi khi có sự kiện click.
  • Cách này giúp tách biệt logic giao diện (class Button) và logic hành động (callback).

🎯 Use case:

    Ví dụ:
  • Gán sự kiện on_press cho nút “Save”.
  • Đăng ký on_data_received trong socket hoặc MQTT client.
  • Định nghĩa on_success khi API trả về kết quả thành công.


✅ Tổng kết:

  • First-class functions cho phép bạn truyền logic hành vi như một dữ liệu.
  • Kết hợp với OOP, bạn có thể thiết kế các class cực kỳ linh hoạt mà không cần subclass hoặc override.
  • Đây là tư duy cốt lõi giúp Python viết code ngắn, rõ và dễ mở rộng — đặc biệt trong lập trình nhúng, GUI, hoặc backend event-driven.

4 - Lưu ý, best practices & hạn chế

  • Luôn truyền self làm tham số đầu tiên trong instance method.
  • Không nên đổi tên self trừ khi có lý do đặc biệt.
  • Khi không cần truy cập instance, dùng @staticmethod hoặc @classmethod.
  • Tránh lạm dụng lambda — chỉ dùng khi hàm ngắn gọn.
  • Hiểu rõ cách self hoạt động giúp bạn tránh bug khi truyền tham chiếu sai.

    Tóm lại: — First-class functions cho phép bạn làm việc với hàm như dữ liệu. — self giúp methods truy cập và thao tác với chính đối tượng của class. Khi nắm vững hai khái niệm này, bạn sẽ viết được mã Python hướng đối tượng và hướng hàm một cách hiệu quả, linh hoạt và dễ bảo trì hơn.

>>>>>> Follow ngay <<<<<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn
//