Trong Python, các đối số của phương thức phải được chỉ định bên trong cặp ngoặc đơn. Điều này là do cả hàm và phương thức đều sử dụng ngoặc đơn để biểu thị việc gọi thực thi. Nếu bạn sử dụng ngoặc vuông để gọi một phương thức, bạn sẽ gặp lỗi TypeError: 'method' object is not subscriptable.
Hiểu về lỗi TypeError: 'method' object is not subscriptable
Các đối tượng có thể subscription (subscriptable) là những đối tượng có phương thức __getitem__. Chúng bao gồm các kiểu dữ liệu như danh sách (list), từ điển (dictionary) và tuple. Phương thức __getitem__ cho phép trình thông dịch Python truy xuất một phần tử riêng lẻ từ một tập hợp.
Không phải tất cả các đối tượng đều có thể subscription. Ví dụ, các phương thức (method) thì không. Điều này là do chúng không triển khai phương thức __getitem__. Do đó, bạn không thể sử dụng cú pháp ngoặc vuông để truy cập các mục trong một phương thức hoặc để gọi một phương thức.
Xét đoạn mã sau:
cheeses = ["Edam", "Stilton", "English Cheddar", "Parmesan"] print(cheeses[0])
Mã này trả về "Edam", loại phô mai tại vị trí chỉ mục 0. Chúng ta không thể sử dụng ngoặc vuông để gọi một hàm hoặc phương thức vì hàm và phương thức không phải là đối tượng có thể subscription.
Ví dụ minh họa
Chúng ta sẽ xây dựng một chương trình lưu trữ các loại phô mai trong các đối tượng. Lớp "Cheese" mà chúng ta sử dụng để định nghĩa một loại phô mai sẽ có một phương thức cho phép kiểm tra xem một loại phô mai có đến từ một quốc gia cụ thể hay không.
Đầu tiên, định nghĩa một lớp cho các loại phô mai. Chúng ta gọi lớp này là Cheese:
class Cheese:
def __init__(self, name, origin):
self.name = name
self.origin = origin
def get_country(self, to_compare):
if to_compare == self.origin:
print("{} is from {}.".format(self.name, self.origin))
else:
print("{} is not from {}. It is from {}.".format(self.name, to_compare, self.origin))
Lớp của chúng ta chứa hai phương thức. Phương thức đầu tiên định nghĩa cấu trúc của đối tượng Cheese. Phương thức thứ hai cho phép chúng ta kiểm tra xem quốc gia xuất xứ của một loại phô mai có bằng một giá trị cụ thể hay không.
Tiếp theo, chúng ta tạo một đối tượng từ lớp Cheese:
edam = Cheese("Edam", "Netherlands")
Biến "edam" là một đối tượng. Tên liên kết với loại phô mai là Edam và quốc gia xuất xứ của nó là Hà Lan.
Bây giờ, hãy gọi phương thức get_country() của chúng ta:
edam.get_country["Germany"]
Mã này thực thi phương thức get_country() từ lớp Cheese. Phương thức get_country() kiểm tra xem giá trị của "origin" trong đối tượng "edam" của chúng ta có bằng "Germany" hay không.
Chạy mã và xem kết quả:
Traceback (most recent call last): File "main.py", line 14, inedam.get_country["Germany"] TypeError: 'method' object is not subscriptable
Một lỗi xảy ra trong mã của chúng ta.
Giải pháp
Hãy phân tích dòng mã mà trình gỡ lỗi Python đã xác định là gây ra lỗi:
edam.get_country["Germany"]
Trong dòng mã này, chúng ta sử dụng ngoặc vuông để gọi phương thức get_country(). Đây là cú pháp không được chấp nhận vì ngoặc vuông được dùng để truy cập các mục từ một danh sách. Vì hàm và đối tượng không phải là đối tượng có thể subscription, chúng ta không thể sử dụng ngoặc vuông để gọi chúng.
Để khắc phục lỗi này, chúng ta phải thay thế ngoặc vuông bằng ngoặc đơn:
edam.get_country("Germany")
Chạy mã lại và xem kết quả:
Edam is not from Germany. It is from Netherlands.
Mã của chúng ta thực thi thành công. Hãy thử kiểm tra xem Edam có phải từ "Netherlands" không để đảm bảo hàm hoạt động trong mọi trường hợp, dù giá trị chúng ta chỉ định có bằng quốc gia xuất xứ của loại phô mai hay không:
edam.get_country("Netherlands")
Mã trả về:
Edam is from Netherlands.
Mã hoạt động đúng dù giá trị chúng ta chỉ định có bằng quốc gia xuất xứ của loại phô mai hay không.
Kết luận
Lỗi TypeError: 'method' object is not subscriptable xảy ra khi bạn sử dụng ngoặc vuông để gọi một phương thức bên trong một lớp. Để khắc phục lỗi này, hãy đảm bảo rằng bạn chỉ gọi các phương thức của một lớp bằng cách sử dụng ngoặc đơn sau tên phương thức bạn muốn gọi.
Bây giờ bạn đã sẵn sàng giải quyết lỗi Python phổ biến này như một lập trình viên chuyên nghiệp!