Trong bài viết này, chúng ta sẽ tìm hiểu về hai phương thức đặc biệt str()
và repr()
được định nghĩa trong mô hình dữ liệu Python. Chúng có thể hữu ích trong việc debug mã Python bằng cách ghi lại hoặc in ra thông tin hữu ích về một đối tượng.

Các phương thức đặc biệt của Python bắt đầu và kết thúc bằng hai dấu gạch dưới và được gọi không chính thức là dunder methods. Dunder methods là các phương thức nền tảng cho các toán tử và hàm tích hợp của Python. Bạn nên tránh gọi trực tiếp các dunder methods mà thay vào đó hãy triển khai các dunder methods trong class của bạn và sau đó sử dụng các hàm dựng sẵn ( (built-in functions) sẽ gọi chúng, chẳng hạn như str()
và repr()
.
Đâu là sự khác biệt giữa hai phương thức str() và repr()?
Phương thức __str__()
trả về một chuỗi biểu diễn của một đối tượng mà con người có thể đọc được hay còn gọi là chuỗi biểu diễn không chính thức của một đối tượng. Các hàm built-in như print()
, str()
, và format()
sẽ gọi phương thức này. Nếu bạn không định nghĩa (define) phương thức __str__()
cho một class, thì triển khai mặc định của Python sẽ gọi phương thức __repr__()
thay thế.
Phương thức __repr__()
trả về một chuỗi biểu diễn của một đối tượng giàu thông tin hơn, hoặc mang tính chính thức. Phương thức này được gọi bởi hàm built-in repr()
. Nếu có thể, chuỗi được trả về nên là một biểu thức Python hợp lệ có thể được sử dụng để tạo lại đối tượng đó. Trong mọi trường hợp, chuỗi này phải mang tính thông tin và rõ ràng.
Nhìn chung, chuỗi của __str__()
dành cho người dùng, còn chuỗi của __repr__()
dành cho các nhà phát triển.
Ví dụ về __str__()
và __repr__()
với một Built-in Class
Các ví dụ trong phần này sẽ gọi trực tiếp các phương thức __str__()
và __repr__()
chỉ nhằm mục đích minh họa.
Lớp datetime.datetime
là một built-in class của Python, nó đã có sẵn cài đặt mặc định cho các phương thức __str__()
và __repr__()
.
Đoạn mã ví dụ sau đây sẽ cho thấy các chuỗi được trả về bởi cài đặt mặc định của các phương thức __str__()
và __repr__()
cho một đối tượng datetime.datetime
:
import datetime
mydate = datetime.datetime.now()
print("__str__() string: ", mydate.__str__())
print("str() string: ", str(mydate))
print("__repr__() string: ", mydate.__repr__())
print("repr() string: ", repr(mydate))
Kết quả thu được như sau:
Output
__str__() string: 2023-01-27 09:50:37.429078
str() string: 2023-01-27 09:50:37.429078
__repr__() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)
repr() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)
Kết quả đầu ra cho thấy rằng hàm str()
sẽ gọi phương thức __str__()
và trả về một chuỗi dễ đọc, thân thiện với con người. Trong khi đó, hàm repr()
sẽ gọi phương thức __repr__()
và trả về một chuỗi giàu thông tin hơn, chuỗi này thậm chí có thể được dùng để tái tạo lại đối tượng. Trên thực tế, bạn có thể kết hợp hàm repr()
với hàm eval()
để tạo ra một đối tượng mới từ chuỗi đó:
import datetime
mydate1 = datetime.datetime.now()
mydate2 = eval(repr(mydate1))
print("mydate1 repr() string: ", repr(mydate1))
print("mydate2 repr() string: ", repr(mydate2))
print("the values of the objects are equal: ", mydate1==mydate2)
Kết quả đầu ra:
Output
mydate1 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635)
mydate2 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635)
the values of the objects are equal: True
Đoạn code ví dụ trước đó đã tạo ra đối tượng mydate2
từ chuỗi repr()
của mydate1
. Sau đó, nó kiểm tra để xác minh rằng giá trị của cả hai đối tượng là bằng nhau.
Ví dụ về __str__()
và __repr__()
với một Class mới
Khi bạn tạo một class mới, bạn nên triển khai ít nhất là phương thức __repr__()
. Điều này đảm bảo rằng các hàm tích hợp sẵn (built-in functions) khi sử dụng __repr__()
sẽ trả về thông tin hữu ích về đối tượng của bạn.
Class sau đây không triển khai các phương thức __str__()
hoặc __repr__()
:
class Ocean:
def __init__(self, sea_creature_name, sea_creature_age):
self.name = sea_creature_name
self.age = sea_creature_age
c = Ocean('Jellyfish', 5)
print(str(c))
print(repr(c))
Khi bạn sử dụng str()
và repr()
, đầu ra là
Output
<__main__.Ocean object at 0x102892860>
<__main__.Ocean object at 0x102892860>
Ví dụ trước đó cho thấy rằng cài đặt mặc định của __repr__()
cho đối tượng chỉ trả về một chuỗi với tên class và ID đối tượng dưới định dạng hệ thập lục phân, điều này không thực sự hữu ích. Lưu ý rằng str()
và repr()
trả về cùng một giá trị, bởi vì str()
sẽ gọi __repr__()
khi __str__()
không được triển khai.
Bây giờ, hãy cập nhật class Ocean
với cài đặt của các phương thức __str__()
và __repr__()
:
class Ocean:
def __init__(self, sea_creature_name, sea_creature_age):
self.name = sea_creature_name
self.age = sea_creature_age
def __str__(self):
return f'The creature type is {self.name} and the age is {self.age}'
def __repr__(self):
return f'Ocean(\\'{self.name}\\', {self.age})'
c = Ocean('Jellyfish', 5)
print(str(c))
print(repr(c))
Đầu ra là:
Output
The creature type is Jellyfish and the age is 5
Ocean('Jellyfish', 5)
Việc triển khai __str__()
trong ví dụ trước đó trả về một chuỗi dễ đọc, cung cấp các chi tiết liên quan của đối tượng cho người dùng. Còn việc triển khai __repr__()
thì trả về một chuỗi là một biểu thức Python hợp lệ, có thể được sử dụng để tái tạo lại đối tượng: Ocean('Jellyfish', 5)
. Ví dụ này sử dụng f-string formatting cho các chuỗi, nhưng bạn có thể định dạng chuỗi bằng bất kỳ định dạng nào được Python hỗ trợ.
Kết Luận
Trong bài viết này, bạn đã tìm hiểu sự khác biệt giữa các phương thức __str__()
và __repr__()
, đồng thời đã triển khai các phương thức đặc biệt này trong một class. Nhờ đó, bạn không cần gọi chúng trực tiếp mà có thể sử dụng các hàm tích hợp sẵn như str()
và repr()
. Để tìm hiểu thêm về cách làm việc với chuỗi trong Python, bạn có thể tham khảo các bài hướng dẫn về Python string của chúng tôi.