Tìm hiểu về nạp chồng hàm trong Python

Nạp chồng hàm là một tính năng trong một số ngôn ngữ lập trình cho phép bạn xác định các biến thể của cùng một hàm. Mỗi biến thể có cùng tên, nhưng cách triển khai khác nhau, với các chữ ký chức năng duy nhất.
Kỹ thuật này cho phép bạn thực hiện các thao tác khác nhau dựa trên loại và số lượng đối số được truyền cho hàm.
Không giống như các ngôn ngữ như C++ và Java, Python không hỗ trợ nạp chồng hàm theo mặc định, nhưng có nhiều cách để đạt được chức năng tương tự.
Mục lục
Python xử lý quá tải hàm như thế nào?
Trong Python, bạn có thể định nghĩa cùng một hàm nhiều lần với các tham số, kiểu dữ liệu khác nhau hoặc cả hai trong mỗi định nghĩa. Tuy nhiên, Python sẽ chỉ nhận ra định nghĩa cuối cùng của hàm khi bạn gọi nó. Đây là một ví dụ:
def arithmetics(a, b):
return a - bdef arithmetics(a, b, c, d):
return a + b - c * dprint(arithmetics(1, 2, 3, 5))
print(arithmetics(1, 2))
Các ngôn ngữ hướng đối tượng, như Java, thường hỗ trợ nạp chồng hàm và phương thức. Một phương thức đơn giản là một hàm mà bạn định nghĩa bên trong một lớp.
Trong đoạn mã trên, Python sẽ chỉ nhận ra định nghĩa thứ hai của hàm số học() khi bạn cố gắng gọi nó trong dự án của mình. Nếu bạn cố gắng gọi hàm có hai đối số như được xác định lần đầu, bạn sẽ gặp lỗi “thiếu đối số vị trí bắt buộc”.
Bạn sẽ không gặp lỗi khi gọi hàm có bốn đối số. Điều này có nghĩa là Python đã ghi đè hàm bằng phiên bản mới nhất của nó. Đây không phải là hành vi quá tải nên bạn cần giải quyết nó.
Vì vậy, Python không xử lý việc nạp chồng hàm theo mặc định, nhưng có một số thủ thuật bạn có thể sử dụng để mô phỏng hành vi của nó trong chương trình của mình.
Phương pháp 1: Sử dụng tham số tùy chọn hoặc đối số mặc định
Bạn có thể đạt được tình trạng quá tải bằng cách xác định hàm với các đối số mặc định. Đây là một ví dụ:
def arithmetics(a, b=0, c=0):
"""
Arguments:
a: The first number.
b: The second number (optional).
c: The third number (optional).
"""
return a - b + c
Hàm này có ba tham số, nhưng hai trong số chúng có giá trị mặc định. Điều này có nghĩa là bạn có thể gọi nó với từ một đến ba đối số:
print(arithmetics(1))
print(arithmetics(2, 5))
print(arithmetics(10, 3, 4))
Mặc dù cách tiếp cận này cho phép bạn gọi hàm theo nhiều cách khác nhau nhưng về lâu dài nó không hiệu quả lắm. Dưới đây là một số hạn chế của nó:
- Bạn chỉ có thể truyền các đối số là số nguyên hoặc số float.
- Không có thay đổi đáng kể trong hoạt động của chức năng. Ví dụ: bạn không thể thay đổi hành vi của nó để tính diện tích hình hoặc thậm chí in Hello World.
Phương pháp 2: Sử dụng đối số biến
Để sử dụng các đối số biến để nạp chồng hàm trong Python, bạn nên bao gồm tham số args khi xác định hàm của mình. Tham số args cho phép bạn truyền nhiều đối số vị trí khi gọi hàm. Đây là một ví dụ:
def arithmetics(a, *args):
"""
Arguments:
a: The first number.
*args: A variable number of arguments (optional).
"""
args_sum = 0for num in args:
args_sum *= numreturn a - args_sum
print(arithmetics(1))
print(arithmetics(2, 5))
print(arithmetics(10, 3, 4, 2, 4, 6))
Hàm trên nhận hai đối số: một đối số bắt buộc được gọi là a và đối số args, cho phép bạn nhập bao nhiêu đối số tùy thích.
Mặc dù có thể nhận nhiều đối số nhưng hàm trên chỉ có thể thực hiện thao tác nhân trên các đối số biến, tức là các đối số được biểu thị bằng từ khóa args.
Nếu muốn thực hiện nhiều thao tác, bạn phải đưa các câu lệnh có điều kiện vào mã của mình và điều này có thể nhanh chóng trở nên phức tạp.
Phương pháp 3: Sử dụng Trình trang trí nhiều công văn
Trình trang trí nhiều công văn là một thư viện Python cho phép bạn xác định nhiều cách triển khai hoặc phiên bản của một hàm, dựa trên loại đối số của hàm đó. Điều này có nghĩa là bạn có thể xác định cùng một hàm với các kiểu dữ liệu khác nhau và thay đổi hoàn toàn hành vi của nó.
Để sử dụng trình trang trí nhiều công văn, hãy làm theo các bước sau:
pip install multipledispatch
from multipledispatch import dispatch@dispatch(data type1, data type2, data typeX)
def your_function(a, b, c, x):
pass
Đây là một ví dụ sử dụng trình trang trí nhiều công văn để nạp chồng hàm trong Python:
from multipledispatch import dispatch@dispatch(int, int)
def add(a, b):
"""
Arguments:
a: Any integer.
b: Any integer.
"""
return a + b@dispatch(int, list)
def add(a, b):
"""
Arguments:
a: Any integer.
b: Any Python list.
"""
b.append(a)
return b
print(add(1, 2))
print(add(1, [2, 3, 4, 5, 'w', 'done']))
Đoạn mã ở trên xác định hai phiên bản của hàm add(). Trường hợp đầu tiên lấy hai số nguyên làm đối số và trả về tổng của chúng.
Trong khi đó, phiên bản thứ hai của hàm này nhận số nguyên và danh sách. Nó nối số nguyên vào danh sách và trả về danh sách mới.
Cách tiếp cận nạp chồng hàm trong Python này mang lại cho bạn rất nhiều tính linh hoạt, đặc biệt nếu bạn cần thay đổi hành vi của phương thức của mình. Bạn có thể tìm hiểu thêm từ nhiều tài liệu công văn.
Cách tiếp cận tốt nhất đối với việc nạp chồng hàm trong Python
Cách tiếp cận bạn thực hiện để nạp chồng hàm sẽ phụ thuộc vào điều bạn đang cố gắng đạt được. Nếu bạn có thể hoàn thành nhiệm vụ của mình bằng cách sử dụng các đối số mặc định hoặc biến, thì trình trang trí nhiều công văn có thể là quá mức cần thiết. Tuy nhiên, bộ trang trí nhiều công văn thường là lựa chọn tốt nhất vì tính hiệu quả và độ chính xác của nó.
Trình trang trí này cung cấp một cách rõ ràng và linh hoạt để triển khai nạp chồng hàm trong Python. Nó cho phép bạn xác định nhiều cách triển khai của một hàm dựa trên loại đối số của nó.
Với phương pháp này, bạn có thể tạo các hàm linh hoạt có thể chấp nhận các loại tham số khác nhau mà không cần các câu lệnh điều kiện phức tạp.