Mục đích của __Vpr__ của Python


139
def __repr__(self):
  return '<%s %s (%s:%s) %s>' % (
    self.__class__.__name__, self.urlconf_name, self.app_name,
    self.namespace, self.regex.pattern)

Ý nghĩa / mục đích của phương pháp này là gì?


@ zjm1126: bạn có muốn biết tại sao >>> variablein những gì __repr__()trả về?
Esteban Küber

18
Tài liệu đó đưa mọi người vào giấc ngủ. Thêm vào đó, thật hữu ích khi học hỏi từ những người khác cách sử dụng nó.
Quan


2
Đối với các nhà phát triển Java đang học Python, cách tốt nhất để xem xét điều này là toString () trong Java.
Ravi

Câu trả lời:


187

__repr__sẽ trả về một đại diện có thể in của đối tượng, rất có thể là một trong những cách có thể để tạo đối tượng này. Xem tài liệu chính thức tại đây . __repr__là nhiều hơn cho các nhà phát triển trong khi __str__là cho người dùng cuối.

Một ví dụ đơn giản:

>>> class Point:
...   def __init__(self, x, y):
...     self.x, self.y = x, y
...   def __repr__(self):
...     return 'Point(x=%s, y=%s)' % (self.x, self.y)
>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)

2
lazy1: Tôi chủ yếu muốn sửa định dạng (thật hữu ích khi có các ví dụ khớp gần nhất có thể với những gì họ sẽ thấy trong một phiên mẫu), nhưng tôi cũng điều chỉnh định dạng đầu ra để khác biệt rõ ràng với bài tập, vì điều đó cải thiện đáng kể sự rõ ràng cho ai đó nhầm lẫn về điều này, imho. (Nếu tôi đã đi xa, chỉ cần chỉnh sửa lại và tôi sẽ nợ bạn một cốc bia.)


1
Điều này có thể nên sử dụng% r thay vì% s: stackoverflow.com/questions/6005159/ Khăn
Jonathan Adelson

43
Điều này không thực sự chính xác. __str__là đầu ra được cho là có thể đọc được của con người: __repr__được coi là một đại diện có thể đọc được cho trình thông dịch Python (tức là cung cấp chuỗi cho trình thông dịch nên tạo lại đối tượng). __str__Tuy nhiên, nếu một đối tượng không có phương thức, __repr__được sử dụng thay thế. Cũng như đã lưu ý: ví dụ này thực sự in __str__phương thức self.xself.y: %rnên được sử dụng thay vì %strong hoạt động định dạng chuỗi (vì lớp không xác định __str__, __repr__dù sao cũng thực sự được trả về, nhưng nó là một sự bất thường).
Daniel Andersson

20

Điều này được giải thích khá tốt trong tài liệu Python :

repr ( object ): Trả về một chuỗi chứa một đại diện có thể in được của một đối tượng. Đây là cùng một giá trị mang lại bởi chuyển đổi (báo giá ngược). Đôi khi rất hữu ích khi có thể truy cập hoạt động này như một chức năng thông thường. Đối với nhiều loại, hàm này thực hiện một nỗ lực trả về một chuỗi sẽ mang lại một đối tượng có cùng giá trị khi được truyền vào eval(), nếu không, biểu diễn là một chuỗi được đặt trong dấu ngoặc nhọn chứa tên của loại đối tượng cùng với thông tin bổ sung thường bao gồm tên và địa chỉ của đối tượng. Một lớp có thể kiểm soát những gì hàm này trả về cho các thể hiện của nó bằng cách định nghĩa một __repr__()phương thức.

Vì vậy, những gì bạn đang thấy ở đây là cài đặt mặc định __repr__, rất hữu ích cho việc tuần tự hóa và gỡ lỗi.


5
Tôi nghĩ rằng phương pháp trích dẫn ngược (hoặc 'backticks') để lấy "đại diện" của một đối tượng bị phản đối và đã bị xóa cho phiên bản 3.0
MatrixFrog

MatrixFrog: cả hai đều đúng, nhưng tài liệu 2.x hiện tại vẫn nói điều này, đó là nơi trích dẫn.

Đối với nhiều đối tượng, __Vpr__ và __str__ là cùng một hàm. Trong thực tế, nếu bạn chỉ xác định __str__, thì __Vpr__ mặc định chỉ gọi __str__. Trường hợp rõ ràng nhất khi điều này không đúng là chính các chuỗi: str ('stackoverflow') trả về stackoverflownhưng repr ('stackoverflow') là 'stackoverflow'.
MatrixFrog

6
Bạn có điều đó ngược lại, __Vpr__ không bao giờ sử dụng __str__, nhưng điều ngược lại có thể xảy ra. Xem docs.python.org/reference/ trộm

13

__repr__được trình thông dịch Python độc lập sử dụng để hiển thị một lớp ở định dạng có thể in được. Thí dụ:

~> python3.5
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class StackOverflowDemo:
...     def __init__(self):
...         pass
...     def __repr__(self):
...         return '<StackOverflow demo object __repr__>'
... 
>>> demo = StackOverflowDemo()
>>> demo
<StackOverflow demo object __repr__>

Trong trường hợp một __str__phương thức không được định nghĩa trong lớp, nó sẽ gọi __repr__hàm trong một nỗ lực để tạo một biểu diễn có thể in được.

>>> str(demo)
'<StackOverflow demo object __repr__>'

Ngoài ra, print()ing lớp sẽ gọi __str__theo mặc định.


Tài liệu , nếu bạn vui lòng


7

Các __repr__ phương pháp đơn giản là nói với Python làm thế nào để in các đối tượng của một lớp


1

Một ví dụ để thấy sự khác biệt giữa chúng (tôi đã sao chép từ nguồn này ),

>>> x=4
>>> repr(x)
'4'
>>> str(x)
'4'
>>> y='stringy'
>>> repr(y)
"'stringy'"
>>> str(y)
'stringy'

Lợi nhuận của repr()str()giống hệt nhau int x, nhưng có sự khác biệt giữa các giá trị trả về cho str y- một giá trị chính thức và giá trị kia là không chính thức . Một trong những khác biệt quan trọng nhất giữa các biểu diễn chính thức và không chính thức là việc triển khai mặc định __repr__cho giá trị str có thể được gọi là đối số để đánh giá và giá trị trả về sẽ là một đối tượng chuỗi hợp lệ, như sau:

>>> repr(y)
"'a string'"
>>> y2=eval(repr(y))
>>> y==y2
True

Nếu bạn cố gắng gọi giá trị trả về __str__là đối số để đánh giá, kết quả sẽ không hợp lệ.


1

Khi chúng ta tạo các kiểu mới bằng cách định nghĩa các lớp, chúng ta có thể tận dụng các tính năng nhất định của Python để làm cho các lớp mới thuận tiện sử dụng. Một trong những tính năng này là "phương pháp đặc biệt", còn được gọi là "phương pháp ma thuật".

Các phương thức đặc biệt có tên bắt đầu và kết thúc bằng hai dấu gạch dưới. Chúng tôi xác định chúng, nhưng thường không gọi chúng trực tiếp bằng tên. Thay vào đó, họ thực hiện tự động trong các trường hợp cụ thể.

Thật thuận tiện khi có thể xuất giá trị của một thể hiện của một đối tượng bằng cách sử dụng một câu lệnh in. Khi chúng tôi làm điều này, chúng tôi muốn giá trị được thể hiện trong đầu ra ở một số định dạng rõ ràng dễ hiểu. Các repr phương pháp đặc biệt có thể được sử dụng để sắp xếp việc này xảy ra. Nếu chúng ta định nghĩa phương thức này, nó có thể được gọi tự động khi chúng ta in giá trị của một thể hiện của một lớp mà chúng ta đã định nghĩa phương thức này. Tuy nhiên, cần phải đề cập rằng cũng có một phương pháp str đặc biệt, được sử dụng cho mục đích tương tự, nhưng không giống nhau, có thể được ưu tiên, nếu chúng ta cũng đã định nghĩa nó.

Nếu chúng ta chưa định nghĩa, phương thức repr cho lớp Point3D và đã khởi tạo my_point như một thể hiện của Point3D, và sau đó chúng ta thực hiện điều này ...

in my_point ... chúng ta có thể xem đây là đầu ra ...

Không đẹp lắm nhỉ?

Vì vậy, chúng tôi định nghĩa phương thức đặc biệt repr hoặc str , hoặc cả hai, để có đầu ra tốt hơn.

**class Point3D(object):
    def __init__(self,a,b,c):
        self.x = a
        self.y = b
        self.z = c
    def __repr__(self):
        return "Point3D(%d, %d, %d)" % (self.x, self.y, self.z)
    def __str__(self):
        return "(%d, %d, %d)" % (self.x, self.y, self.z)
my_point = Point3D(1, 2, 3)
print my_point # __repr__ gets called automatically
print my_point # __str__ gets called automatically**

Đầu ra ...

(1, 2, 3) (1, 2, 3)


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.