Cả str() và repr() trong Python đều được dùng để biểu diễn chuỗi của một đối tượng. Mặc dù chúng dường như phục vụ cùng mục đích, nhưng có một chút khác biệt giữa chúng.
Bạn có bao giờ nhận thấy điều gì xảy ra khi gọi hàm built-in str(x) trong Python, nơi x là bất kỳ đối tượng nào bạn muốn? Giá trị trả về của str(x) phụ thuộc vào hai phương thức: __str__ là lựa chọn mặc định và __repr__ là phương án dự phòng.
Hãy xem tài liệu Python nói gì về chúng:
>>> help(str)
Help on class str in module builtins:
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object.
>>> help(repr)
Help on built-in function repr in module builtins:
repr(obj, /)
Return the canonical string representation of the object.
For many object types, including most builtins, eval(repr(obj)) == obj.
Bây giờ hãy thử hiểu hai phương thức này qua vài ví dụ:
>>> str(123)
'123'
>>> repr(123)
'123'
>>> # Trên ta thấy - với dữ liệu số nguyên, không có sự khác biệt
>>> # Thử dữ liệu chuỗi trên hai phương thức này
>>> str('Python')
'Python'
>>> repr('Python')
"'Python'"
Giá trị trả về của repr() và str() giống nhau cho giá trị số nguyên, nhưng có sự khác biệt cho chuỗi – một là biểu diễn chính thức (formal) và cái kia là không chính thức (informal).
Nếu theo tài liệu chính thức Python – __str__ dùng để tìm biểu diễn chuỗi "không chính thức" (dễ đọc) của một đối tượng, trong khi __repr__ dùng để tìm biểu diễn chuỗi "chính thức" của một đối tượng.
Sự khác biệt giữa biểu diễn chính thức và không chính thức là việc triển khai mặc định của __repr__ cho giá trị str có thể được gọi làm đối số cho eval, và giá trị trả về sẽ là một đối tượng chuỗi hợp lệ. Hàm này (repr()) lấy một chuỗi và đánh giá nội dung của nó như mã Python.
Vì vậy khi chúng ta truyền "'Python'" cho nó, nó hoạt động. Tuy nhiên, 'Python' dẫn đến lỗi vì nó được hiểu là biến Python mà tất nhiên là chưa định nghĩa. Dưới đây là code để hiểu điều này:
>>> x = "Python"
>>> repr(x)
"'Python'"
>>> x1 = eval(repr(x))
>>> x == x1
True
Vì vậy nếu chúng ta thử gọi giá trị trả về của __str__ làm đối số cho eval, nó sẽ thất bại.
>>> y = "Python"
>>> str(y)
'Python'
>>> y1 = eval(str(y))
Traceback (most recent call last):
File "", line 1, in
y1 = eval(str(y))
File "", line 1, in
NameError: name 'Python' is not defined
Ví dụ khác minh họa sự khác biệt giữa hai phương thức:
>>> import datetime
>>> now = datetime.datetime.now()
>>> str(now)
'2019-03-29 01:29:23.211924'
>>> repr(now)
'datetime.datetime(2019, 3, 29, 1, 29, 23, 211924)'
Trong kết quả trên, str(now) tính toán chuỗi chứa giá trị của now, trong khi repr(now) lại trả về mã Python cần thiết để xây dựng lại đối tượng now của chúng ta.
Các khác biệt chính
| str() | repr() |
|---|---|
| Làm cho đối tượng dễ đọc | Yêu cầu mã tái tạo đối tượng |
| Tạo đầu ra cho người dùng cuối | Tạo đầu ra cho lập trình viên |
Các điểm trên cần được xem xét khi viết __str__ và __repr__ cho các lớp của bạn.