Nắm vững cách sử dụng Đối số (Argument) là bước quan trọng để viết code hiệu quả và linh hoạt hơn. Bài viết này sẽ hướng dẫn bạn từ A-Z: bắt đầu từ khái niệm Đối số là gì, lý do nên dùng chúng, đến việc phân biệt tường tận với Tham số (Parameter). Tiếp theo, chúng ta sẽ đi sâu vào các cách truyền đối số khác nhau, phân tích ví dụ trên Python, JavaScript và lưu ý lỗi thường gặp.
Đối số (Argument) là gì?
Đối số (Argument) là giá trị thực tế mà bạn cung cấp (hay “truyền vào”) cho một hàm (function) hoặc phương thức (method) khi bạn thực hiện lời gọi hàm/phương thức đó. Nói đơn giản, chúng chính là dữ liệu cụ thể, đầu vào mà hàm sẽ sử dụng để thực hiện công việc của mình.
Hãy hình dung bạn có một hàm tên là in_loi_chao
. Hàm này cần biết tên của người cần chào. Khi bạn gọi hàm đó và cung cấp tên “An”, ví dụ in_loi_chao("An")
, thì chuỗi "An"
chính là đối số bạn đã truyền vào.
Nếu không có đối số, nhiều hàm sẽ trở nên kém linh hoạt vì chúng chỉ có thể hoạt động trên dữ liệu cố định hoặc không có dữ liệu đầu vào nào cả. Đối số làm cho hàm trở nên mạnh mẽ và tái sử dụng được trong nhiều tình huống khác nhau.
Tại sao cần sử dụng Đối số trong lập trình?
Vậy tại sao chúng ta không viết thẳng các giá trị vào trong hàm mà lại cần đến đối số? Câu trả lời nằm ở tính linh hoạt và khả năng tái sử dụng của code. Đối số đóng vai trò cầu nối, mang dữ liệu từ bên ngoài vào xử lý bên trong hàm.
Mục đích chính của việc sử dụng đối số là cho phép hàm nhận và xử lý các dữ liệu đầu vào khác nhau mỗi khi nó được gọi. Thay vì viết nhiều hàm gần giống hệt nhau chỉ khác về giá trị xử lý, bạn chỉ cần viết một hàm và truyền các giá trị khác nhau thông qua đối số.
Ví dụ, thay vì viết hàm tinh_tong_5_va_3()
và tinh_tong_10_va_20()
, bạn chỉ cần viết một hàm tinh_tong(so_thu_nhat, so_thu_hai)
duy nhất. Sau đó, bạn có thể gọi tinh_tong(5, 3)
hoặc tinh_tong(10, 20)
, truyền các đối số khác nhau để nhận kết quả tương ứng. Điều này giúp code ngắn gọn, dễ bảo trì hơn.
Sử dụng đối số giúp các hàm trở thành những khối xây dựng (building blocks) độc lập và mạnh mẽ. Chúng nhận đầu vào qua đối số, thực hiện một nhiệm vụ cụ thể, và có thể trả về kết quả. Điều này thúc đẩy việc module hóa code, một nguyên tắc quan trọng trong phát triển phần mềm.
Phân biệt Đối số (Argument) và Tham số (Parameter): Không còn nhầm lẫn!
Đây là điểm cực kỳ quan trọng và thường gây nhầm lẫn cho người mới học: sự khác biệt giữa Đối số (Argument) và Tham số (Parameter). Mặc dù liên quan chặt chẽ, chúng không phải là một. Hiểu rõ sự khác biệt này là nền tảng để làm việc hiệu quả với hàm.
Nói một cách ngắn gọn nhất:
- Tham số (Parameter): Là biến được khai báo trong phần định nghĩa của hàm/phương thức. Nó giống như một “chỗ giữ chỗ” cho giá trị sẽ được truyền vào.
- Đối số (Argument): Là giá trị thực tế được truyền vào hàm khi hàm đó được gọi. Nó là thứ sẽ được gán vào “chỗ giữ chỗ” (tham số) kia.
Tham số (Parameter) là gì?
Tham số (tiếng Anh: Parameter) là tên biến được liệt kê bên trong cặp dấu ngoặc đơn ()
khi bạn định nghĩa (khai báo) một hàm. Chúng hoạt động như những biến cục bộ (local variables) bên trong hàm, chỉ tồn tại trong phạm vi của hàm đó.
Khi định nghĩa hàm, bạn chỉ định những tham số mà hàm đó mong đợi nhận được. Ví dụ, trong định nghĩa hàm sau bằng Python:
Python
def chao_mung(ten_nguoi_dung): # 'ten_nguoi_dung' chính là tham số (parameter)
print(f"Xin chào, {ten_nguoi_dung}!")
Ở đây, ten_nguoi_dung
là một tham số. Nó đóng vai trò như một cái tên đại diện, một chỗ giữ chỗ, cho biết rằng hàm chao_mung
cần nhận một giá trị nào đó (mà chúng ta tạm gọi là ten_nguoi_dung
) để có thể hoạt động.
Điểm khác biệt chính giữa Argument và Parameter
Để dễ hình dung hơn, hãy xem bảng so sánh nhanh và ví dụ cụ thể sau:
Đặc điểm | Tham số (Parameter) | Đối số (Argument) |
---|---|---|
Xuất hiện ở | Định nghĩa hàm (Function Definition) | Lời gọi hàm (Function Call) |
Bản chất là | Biến (Variable) | Giá trị thực tế (Actual Value) |
Vai trò | Chỗ giữ chỗ, tên đại diện cho đầu vào | Dữ liệu cụ thể được cung cấp cho hàm |
Ví dụ (Code) | def ham(tham_so): |
ham(doi_so) |
Xuất sang Trang tính
Ví dụ minh họa:
Hãy xem xét lại hàm tinh_tong
trong Python:
Python
# --- Định nghĩa hàm ---
def tinh_tong(so_hang_1, so_hang_2): # so_hang_1 và so_hang_2 là các THAM SỐ (Parameters)
"""Hàm này nhận vào hai tham số và trả về tổng của chúng."""
tong = so_hang_1 + so_hang_2
return tong
# --- Lời gọi hàm ---
ket_qua = tinh_tong(5, 10) # 5 và 10 là các ĐỐI SỐ (Arguments)
print(f"Kết quả phép cộng là: {ket_qua}") # Output: Kết quả phép cộng là: 15
Trong đoạn code trên:
so_hang_1
vàso_hang_2
trong dòngdef tinh_tong(...)
là các tham số (parameters). Chúng là tên biến được định nghĩa cùng với hàm.- Số
5
và số10
trong dòngtinh_tong(5, 10)
là các đối số (arguments). Chúng là những giá trị thực tế mà chúng ta truyền vào hàm khi gọi nó. Giá trị5
sẽ được gán cho tham sốso_hang_1
, và10
được gán choso_hang_2
bên trong hàm.
Việc phân biệt rõ ràng này giúp bạn đọc hiểu code dễ dàng hơn và tránh các lỗi logic khi làm việc với hàm. Luôn nhớ: tham số ở định nghĩa, đối số ở lời gọi.
Các cách truyền Đối số (Argument Passing) phổ biến
Khi gọi một hàm, bạn có thể truyền đối số theo nhiều cách khác nhau. Các ngôn ngữ lập trình thường hỗ trợ một số cơ chế phổ biến. Việc hiểu các cách này giúp bạn viết code linh hoạt và dễ đọc hơn. Dưới đây là các cách truyền đối số chính thường gặp:
1. Truyền đối số theo vị trí (Positional Arguments)
Đây là cách truyền đối số phổ biến và cơ bản nhất. Các đối số được truyền vào hàm sẽ được gán cho các tham số tương ứng dựa trên vị trí (thứ tự) của chúng. Đối số đầu tiên gán cho tham số đầu tiên, đối số thứ hai gán cho tham số thứ hai, và cứ thế tiếp tục.
Cơ chế hoạt động: Ngôn ngữ lập trình tự động khớp giá trị bạn cung cấp với biến tham số ở cùng vị trí trong định nghĩa hàm.
Ưu điểm: Ngắn gọn, dễ viết khi số lượng tham số ít. Nhược điểm: Phải nhớ chính xác thứ tự các tham số. Nếu truyền sai thứ tự, có thể dẫn đến lỗi logic hoặc kết quả không mong muốn. Khó đọc hiểu khi hàm có nhiều tham số.
Ví dụ (Python):
Python
def gioi_thieu(ten, tuoi, thanh_pho):
"""Hàm giới thiệu thông tin cá nhân."""
print(f"Tên tôi là {ten}.")
print(f"Tôi {tuoi} tuổi.")
print(f"Tôi đến từ {thanh_pho}.")
# Gọi hàm với đối số theo vị trí
gioi_thieu("Bình", 30, "Hà Nội")
# Output:
# Tên tôi là Bình.
# Tôi 30 tuổi.
# Tôi đến từ Hà Nội.
# Nếu truyền sai thứ tự:
gioi_thieu(30, "Hà Nội", "Bình") # Sai logic!
# Output:
# Tên tôi là 30.
# Tôi Hà Nội tuổi.
# Tôi đến từ Bình.
Trong ví dụ trên, "Bình"
được gán cho ten
, 30
cho tuoi
, và "Hà Nội"
cho thanh_pho
vì chúng ở các vị trí tương ứng. Việc đảo thứ tự gây ra kết quả sai.
2. Truyền đối số theo từ khóa (Keyword Arguments)
Để khắc phục nhược điểm của việc phải nhớ thứ tự, nhiều ngôn ngữ hỗ trợ truyền đối số theo từ khóa (tên tham số). Bạn chỉ định rõ ràng tên tham số và giá trị đối số tương ứng khi gọi hàm, sử dụng cú pháp ten_tham_so=gia_tri
.
Cơ chế hoạt động: Ngôn ngữ lập trình tìm tham số có tên trùng khớp và gán giá trị đối số cho nó, không phụ thuộc vào vị trí.
Ưu điểm: Code rõ ràng, dễ đọc hơn vì bạn biết chính xác giá trị nào được gán cho tham số nào. Không cần nhớ thứ tự tham số. Cho phép bỏ qua các tham số có giá trị mặc định (sẽ nói ở phần sau). Nhược điểm: Viết dài hơn một chút so với positional arguments.
Ví dụ (Python):
Python
def gioi_thieu(ten, tuoi, thanh_pho):
"""Hàm giới thiệu thông tin cá nhân."""
print(f"Tên tôi là {ten}.")
print(f"Tôi {tuoi} tuổi.")
print(f"Tôi đến từ {thanh_pho}.")
# Gọi hàm với đối số theo từ khóa (thứ tự không quan trọng)
gioi_thieu(tuoi=25, thanh_pho="Đà Nẵng", ten="Châu")
# Output:
# Tên tôi là Châu.
# Tôi 25 tuổi.
# Tôi đến từ Đà Nẵng.
# Có thể kết hợp positional và keyword (positional phải đứng trước)
gioi_thieu("Dũng", thanh_pho="TP.HCM", tuoi=28)
# Output:
# Tên tôi là Dũng.
# Tôi 28 tuổi.
# Tôi đến từ TP.HCM.
Với keyword arguments, thứ tự tuoi
, thanh_pho
, ten
trong lời gọi hàm không quan trọng, miễn là tên khớp với tham số trong định nghĩa hàm.
3. Sử dụng Đối số mặc định (Default Arguments)
Đôi khi, một số tham số của hàm thường có một giá trị phổ biến. Thay vì bắt buộc người dùng phải luôn cung cấp đối số cho chúng, bạn có thể định nghĩa giá trị mặc định (default value) cho tham số ngay trong phần định nghĩa hàm.
Cơ chế hoạt động: Nếu khi gọi hàm, bạn không cung cấp đối số cho tham số có giá trị mặc định, thì hàm sẽ tự động sử dụng giá trị mặc định đó. Nếu bạn có cung cấp đối số, giá trị bạn cung cấp sẽ ghi đè lên giá trị mặc định.
Lưu ý quan trọng: Trong nhiều ngôn ngữ (như Python), các tham số có giá trị mặc định phải được đặt sau các tham số không có giá trị mặc định trong danh sách tham số khi định nghĩa hàm.
Ưu điểm: Giúp lời gọi hàm ngắn gọn hơn khi các giá trị mặc định là phù hợp. Tăng tính linh hoạt cho hàm. Nhược điểm: Cần cẩn thận khi sử dụng giá trị mặc định là các đối tượng có thể thay đổi (mutable objects) như list hoặc dictionary trong Python, vì chúng có thể gây ra hành vi không mong muốn.
Ví dụ (Python):
Python
def gui_loi_nhan(nguoi_nhan, loi_nhan, nguoi_gui="Hệ thống"): # 'nguoi_gui' có giá trị mặc định
"""Hàm gửi lời nhắn."""
print(f"Gửi tới: {nguoi_nhan}")
print(f"Lời nhắn: {loi_nhan}")
print(f"Người gửi: {nguoi_gui}")
print("-" * 10)
# Gọi hàm không cung cấp 'nguoi_gui', sẽ dùng giá trị mặc định "Hệ thống"
gui_loi_nhan("Anh Khoa", "Chúc mừng sinh nhật!")
# Output:
# Gửi tới: Anh Khoa
# Lời nhắn: Chúc mừng sinh nhật!
# Người gửi: Hệ thống
# ----------
# Gọi hàm và cung cấp 'nguoi_gui', ghi đè giá trị mặc định
gui_loi_nhan("Chị Mai", "Hẹn gặp vào cuối tuần.", nguoi_gui="Em Lan")
# Output:
# Gửi tới: Chị Mai
# Lời nhắn: Hẹn gặp vào cuối tuần.
# Người gửi: Em Lan
# ----------
4. Đối số có độ dài thay đổi (Variable-length Arguments)
Trong một số trường hợp, bạn muốn hàm có thể chấp nhận một số lượng đối số không xác định trước. Ví dụ, hàm tính tổng của bao nhiêu số cũng được, hay hàm xử lý các cặp cấu hình key-value tùy ý. Các ngôn ngữ lập trình cung cấp cơ chế để xử lý việc này.
Cơ chế hoạt động:
- Đối số vị trí không xác định (vd:
*args
trong Python): Cho phép hàm nhận một số lượng bất kỳ các đối số vị trí. Bên trong hàm, các đối số này được gói gọn vào một tuple (trong Python) hoặc một cấu trúc tương tự. - Đối số từ khóa không xác định (vd:
**kwargs
trong Python): Cho phép hàm nhận một số lượng bất kỳ các đối số từ khóa. Bên trong hàm, chúng được gói gọn vào một dictionary (trong Python).
Ưu điểm: Cực kỳ linh hoạt, cho phép hàm xử lý nhiều loại đầu vào khác nhau mà không cần định nghĩa trước tất cả các tham số. Nhược điểm: Cần xử lý cẩn thận các đối số này bên trong hàm. Có thể làm chữ ký hàm (function signature) kém rõ ràng nếu lạm dụng.
Ví dụ (Python):
Python
def tinh_tong_linh_hoat(*cac_so_hang): # *args: nhận nhiều đối số vị trí
"""Hàm tính tổng của một số lượng số hạng bất kỳ."""
print(f"Các đối số nhận được: {cac_so_hang}") # cac_so_hang là một tuple
tong = 0
for so in cac_so_hang:
tong += so
return tong
def in_thong_tin(**chi_tiet): # **kwargs: nhận nhiều đối số từ khóa
"""Hàm in ra các thông tin chi tiết dưới dạng key-value."""
print(f"Các đối số nhận được: {chi_tiet}") # chi_tiet là một dictionary
for key, value in chi_tiet.items():
print(f"- {key}: {value}")
# Ví dụ sử dụng *args
print(f"Tổng 1: {tinh_tong_linh_hoat(1, 2, 3)}")
# Output:
# Các đối số nhận được: (1, 2, 3)
# Tổng 1: 6
print(f"Tổng 2: {tinh_tong_linh_hoat(10, 20, 30, 40, 50)}")
# Output:
# Các đối số nhận được: (10, 20, 30, 40, 50)
# Tổng 2: 150
print("-" * 10)
# Ví dụ sử dụng **kwargs
in_thong_tin(ten="Văn", tuoi=22, nghe_nghiep="Lập trình viên", thanh_pho="Huế")
# Output:
# Các đối số nhận được: {'ten': 'Văn', 'tuoi': 22, 'nghe_nghiep': 'Lập trình viên', 'thanh_pho': 'Huế'}
# - ten: Văn
# - tuoi: 22
# - nghe_nghiep: Lập trình viên
# - thanh_pho: Huế
Việc nắm vững các cách truyền đối số này giúp bạn tận dụng tối đa sức mạnh của hàm trong ngôn ngữ lập trình bạn đang sử dụng.
Ví dụ minh họa Đối số trong các ngôn ngữ lập trình phổ biến
Lý thuyết sẽ dễ hiểu hơn khi đi kèm với ví dụ thực tế. Dưới đây là cách khái niệm đối số và các kiểu truyền đối số được thể hiện trong hai ngôn ngữ lập trình rất phổ biến với người mới bắt đầu: Python và JavaScript.
Ví dụ với Python
Python hỗ trợ đầy đủ các cách truyền đối số chúng ta đã thảo luận: positional, keyword, default, và variable-length (*args
, **kwargs
).
Python
# Định nghĩa hàm với các loại tham số khác nhau
def thong_tin_san_pham(ten_sp, gia, so_luong=1, *ghi_chu, **thong_so_ky_thuat):
"""Hàm mô tả thông tin sản phẩm đa dạng."""
print(f"--- Thông tin sản phẩm ---")
print(f"Tên: {ten_sp}")
print(f"Giá: {gia} VND")
print(f"Số lượng: {so_luong}") # Tham số có giá trị mặc định
if ghi_chu: # Xử lý *args (tuple)
print("Ghi chú thêm:")
for note in ghi_chu:
print(f"- {note}")
if thong_so_ky_thuat: # Xử lý **kwargs (dictionary)
print("Thông số kỹ thuật:")
for key, value in thong_so_ky_thuat.items():
print(f"- {key}: {value}")
print("-" * 25)
# --- Các cách gọi hàm ---
# 1. Chỉ dùng Positional Arguments
thong_tin_san_pham("Laptop XYZ", 20000000)
# 2. Kết hợp Positional và Default (số lượng sẽ là 1)
thong_tin_san_pham("Bàn phím cơ", 1500000)
# 3. Sử dụng Keyword Arguments (ghi đè giá trị mặc định)
thong_tin_san_pham(ten_sp="Màn hình ABC", gia=5000000, so_luong=2)
# 4. Sử dụng *args
thong_tin_san_pham("Chuột không dây", 300000, 5, "Bảo hành 1 năm", "Pin sạc")
# 5. Sử dụng **kwargs
thong_tin_san_pham("Webcam HD", 800000, mau_sac="Đen", do_phan_giai="1080p")
# 6. Kết hợp tất cả
thong_tin_san_pham("Tai nghe Bluetooth", 1200000, 3, "Chống ồn", "Pin 8h", hang="Sony", ket_noi="Bluetooth 5.0")
Giải thích Output (ví dụ 6):
"Tai nghe Bluetooth"
và1200000
là positional arguments choten_sp
vàgia
.3
là positional argument ghi đè giá trị mặc định củaso_luong
."Chống ồn"
và"Pin 8h"
được gom vào tupleghi_chu
(*args).hang="Sony"
vàket_noi="Bluetooth 5.0"
được gom vào dictionarythong_so_ky_thuat
(**kwargs).
Ví dụ với JavaScript
JavaScript cũng có khái niệm đối số, mặc dù cách xử lý có một số khác biệt so với Python, đặc biệt là trước phiên bản ES6 (ECMAScript 2015).
JavaScript
// Định nghĩa hàm trong JavaScript (ES6+)
function gioiThieuNhanVien(ten, tuoi, chucVu = "Nhân viên", ...cacKyNang) {
// chucVu: Tham số có giá trị mặc định (Default Parameter)
// ...cacKyNang: Tham số còn lại (Rest Parameter) - tương tự *args
console.log("--- Thông tin nhân viên ---");
console.log(`Tên: ${ten}`);
console.log(`Tuổi: ${tuoi}`);
console.log(`Chức vụ: ${chucVu}`); // Sẽ dùng "Nhân viên" nếu không được truyền
if (cacKyNang.length > 0) {
console.log("Kỹ năng:");
cacKyNang.forEach(kyNang => { // cacKyNang là một Array
console.log(`- ${kyNang}`);
});
}
console.log("-------------------------");
}
// --- Các cách gọi hàm ---
// 1. Truyền đối số cơ bản (Positional)
gioiThieuNhanVien("Hương", 28); // chucVu sẽ là "Nhân viên"
// 2. Truyền đối số ghi đè giá trị mặc định
gioiThieuNhanVien("Minh", 35, "Trưởng phòng");
// 3. Sử dụng Rest Parameters (...cacKyNang)
gioiThieuNhanVien("Linh", 24, "Thực tập sinh", "JavaScript", "React", "Node.js");
// Lưu ý: JavaScript không có sẵn keyword arguments như Python.
// Tuy nhiên, bạn có thể mô phỏng bằng cách truyền vào một đối tượng (object)
function cauHinhHeThong(config) {
// Giả định config là một object chứa các cài đặt
const mayChu = config.mayChu || "localhost"; // Giá trị mặc định nếu không có
const cong = config.cong || 8080;
const cheDo = config.cheDo || "production";
console.log("--- Cấu hình hệ thống ---");
console.log(`Máy chủ: ${mayChu}`);
console.log(`Cổng: ${cong}`);
console.log(`Chế độ: ${cheDo}`);
console.log("------------------------");
}
// Gọi hàm bằng cách truyền object (mô phỏng keyword arguments)
cauHinhHeThong({ cong: 3000, cheDo: "development" });
cauHinhHeThong({ mayChu: "api.example.com" });
Giải thích:
- JavaScript ES6 giới thiệu Default Parameters (
chucVu = "Nhân viên"
) và Rest Parameters (...cacKyNang
) để xử lý các trường hợp tương tự default arguments và*args
trong Python. Rest parameters gom các đối số vị trí còn lại thành một mảng (Array). - Để mô phỏng Keyword Arguments, một kỹ thuật phổ biến là truyền vào hàm một đối tượng (object literal
{}
) chứa các cặp key-value. Bên trong hàm, bạn truy cập các thuộc tính của đối tượng đó.
Qua các ví dụ này, bạn có thể thấy dù cú pháp có thể khác nhau, ý tưởng cốt lõi về việc sử dụng đối số để truyền dữ liệu vào hàm là tương đồng giữa các ngôn ngữ lập trình.
CÓ THỂ BẠN QUAN TÂM
Để chạy thử code, phát triển dự án hoặc host ứng dụng ổn định, một môi trường mạnh mẽ là rất cần thiết. InterData cung cấp dịch vụ thuê VPS giá rẻ – uy tín – tốc độ cao chỉ từ 3K/ngày, xây dựng trên nền tảng phần cứng AMD EPYC Gen 3th, SSD NVMe U.2 và băng thông cao.
Những lỗi thường gặp khi làm việc với Đối số và cách khắc phục
Khi mới làm quen với đối số và tham số, bạn có thể gặp một số lỗi phổ biến. Nhận biết được chúng sẽ giúp bạn gỡ lỗi (debug) nhanh hơn.
- Lỗi sai số lượng đối số (TypeError: missing required positional argument / takes X positional arguments but Y were given):
- Nguyên nhân: Bạn gọi hàm với số lượng đối số ít hơn hoặc nhiều hơn số lượng tham số mà hàm đó yêu cầu (đối với các tham số bắt buộc, không có giá trị mặc định).
- Khắc phục: Kiểm tra lại định nghĩa hàm để xem nó cần bao nhiêu tham số bắt buộc. Đảm bảo bạn cung cấp đủ số lượng đối số tương ứng khi gọi hàm.
- Lỗi sai kiểu dữ liệu đối số (TypeError / ValueError):
- Nguyên nhân: Bạn truyền vào một đối số có kiểu dữ liệu không phù hợp với phép toán hoặc xử lý bên trong hàm (ví dụ: truyền chuỗi vào hàm mong đợi số để tính toán).
- Khắc phục: Đảm bảo kiểu dữ liệu của đối số bạn truyền vào khớp với kiểu dữ liệu mà hàm mong đợi hoặc có thể xử lý được. Đọc kỹ tài liệu hoặc mã nguồn của hàm nếu cần.
- Nhầm lẫn thứ tự đối số vị trí:
- Nguyên nhân: Khi sử dụng positional arguments, bạn truyền các giá trị không đúng thứ tự so với thứ tự tham số trong định nghĩa hàm. Lỗi này thường không gây ra lỗi chương trình dừng lại (crash) nhưng dẫn đến kết quả sai logic.
- Khắc phục: Kiểm tra kỹ thứ tự tham số trong định nghĩa hàm và đảm bảo bạn truyền đối số theo đúng thứ tự đó. Cân nhắc sử dụng keyword arguments để tăng tính rõ ràng và tránh lỗi này, đặc biệt với các hàm có nhiều tham số.
- Sử dụng giá trị mặc định là đối tượng thay đổi được (Mutable Default Arguments – lỗi tiềm ẩn trong Python):
- Nguyên nhân: Nếu bạn dùng list hoặc dictionary làm giá trị mặc định cho tham số trong Python, giá trị mặc định này chỉ được tạo một lần khi hàm được định nghĩa. Các lần gọi hàm sau đó nếu sửa đổi đối tượng đó sẽ ảnh hưởng lẫn nhau.
- Khắc phục: Quy tắc phổ biến là tránh dùng list hoặc dictionary làm giá trị mặc định trực tiếp. Thay vào đó, hãy đặt giá trị mặc định là
None
và kiểm tra bên trong hàm, nếu làNone
thì mới khởi tạo list/dictionary mới.
Việc chú ý đến những lỗi này và hiểu nguyên nhân sẽ giúp bạn viết code chính xác và đáng tin cậy hơn khi làm việc với các hàm và đối số của chúng.