วัตถุประสงค์ของ __repr__ ของ Python


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

ความสำคัญ / วัตถุประสงค์ของวิธีนี้คืออะไร?


@ zjm1126: อยากรู้ไหมว่าทำไม>>> variableพิมพ์ถึง__repr__()ส่งคืน?
Esteban Küber

21
เอกสารนั้นทำให้คนเข้านอน นอกจากนี้ยังมีประโยชน์ในการเรียนรู้จากผู้อื่นว่าใช้สิ่งนี้อย่างไร
Concerned_Citizen


2
สำหรับนักพัฒนา Java ที่กำลังเรียนรู้ Python วิธีที่ดีที่สุดในการดูสิ่งนี้คือ toString () ใน Java
ราวี

ทุกคลาสใช้ repr ใน python หรือไม่
Charlie Parker

คำตอบ:


195

__repr__ควรส่งคืนการแสดงวัตถุที่พิมพ์ได้ซึ่งส่วนใหญ่เป็นวิธีหนึ่งที่เป็นไปได้ในการสร้างวัตถุนี้ ดูเอกสารอย่างเป็นทางการที่นี่ __repr__เป็นมากกว่าสำหรับนักพัฒนาในขณะที่__str__สำหรับผู้ใช้ปลายทาง

ตัวอย่างง่ายๆ:

>>> 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: ฉันต้องการแก้ไขการจัดรูปแบบเป็นหลัก (การมีตัวอย่างให้ใกล้เคียงที่สุดกับสิ่งที่พวกเขาจะเห็นในเซสชันตัวอย่าง) แต่ฉันยังปรับรูปแบบผลลัพธ์ให้แตกต่างจากการกำหนดอย่างชัดเจนด้วยเช่นกัน ช่วยเพิ่มความชัดเจนอย่างมากสำหรับคนที่สับสนในเรื่องนี้ imho (ถ้าฉันไปไกลแค่แก้ไขใหม่และฉันจะเป็นหนี้คุณเบียร์)

2
ละเว้นการอ้างอิง: docs.python.org/reference/datamodel.html#object.__repr__
S.Lott

1
ซึ่งอาจใช้% r แทน% s: stackoverflow.com/questions/6005159/…
Jonathan Adelson

47
นี่ไม่ถูกต้องจริงๆ __str__เป็นเอาต์พุตที่ควรจะเป็นมนุษย์ที่อ่านได้: __repr__ควรจะเป็นตัวแทนที่อ่านได้สำหรับล่าม Python (เช่นการป้อนสตริงให้กับล่ามควรสร้างวัตถุขึ้นใหม่) หากอ็อบเจ็กต์ไม่มี__str__เมธอดอย่างไรก็ตาม__repr__จะใช้แทน ยังเป็นที่สังเกต: ตัวอย่างนี้จริงพิมพ์__str__วิธีการself.xและself.y: %rควรจะนำมาใช้แทน%sในการดำเนินงานการจัดรูปแบบสตริง (ตั้งแต่ชั้นไม่ได้กำหนด__str__, __repr__จะถูกส่งกลับจริงแล้ว แต่มันก็เป็นความผิดปกติ)
Daniel Andersson

ทุกคลาสใช้ repr ใน python หรือไม่
Charlie Parker

20

สิ่งนี้อธิบายได้ค่อนข้างดีในเอกสาร Python :

repr ( อ็อบเจ็กต์ ): ส่งคืนสตริงที่มีการแสดงอ็อบเจ็กต์ที่พิมพ์ได้ นี่คือมูลค่าเดียวกันที่ได้จากการแปลง (ราคาย้อนกลับ) บางครั้งการเข้าถึงการดำเนินการนี้เป็นฟังก์ชันธรรมดาก็มีประโยชน์ สำหรับหลายประเภทฟังก์ชันนี้จะพยายามส่งคืนสตริงที่จะให้อ็อบเจ็กต์ที่มีค่าเดียวกันเมื่อส่งผ่านไปeval()มิฉะนั้นการแทนค่าจะเป็นสตริงที่อยู่ในวงเล็บเหลี่ยมที่มีชื่อของประเภทของอ็อบเจ็กต์พร้อมกับข้อมูลเพิ่มเติม มักจะรวมชื่อและที่อยู่ของวัตถุ คลาสสามารถควบคุมสิ่งที่ฟังก์ชันนี้ส่งคืนสำหรับอินสแตนซ์ได้โดยการกำหนด__repr__()วิธีการ

สิ่งที่คุณเห็นที่นี่คือการใช้งานเริ่มต้น__repr__ซึ่งมีประโยชน์สำหรับการทำให้เป็นอนุกรมและการดีบัก


5
ฉันคิดว่าวิธีการเสนอราคาย้อนกลับ (หรือ 'backticks') ในการรับ "การแสดง" ของวัตถุนั้นเลิกใช้แล้วและถูกลบออกสำหรับเวอร์ชัน 3.0
MatrixFrog

MatrixFrog: ทั้งจริง แต่เอกสารประกอบ 2.x ปัจจุบันยังคงระบุสิ่งนี้ซึ่งเป็นที่มาของใบเสนอราคา

สำหรับวัตถุจำนวนมาก __repr__ และ __str__ เป็นฟังก์ชันเดียวกัน ในความเป็นจริงถ้าคุณกำหนดเฉพาะ __str__ __repr__ จะมีค่าเริ่มต้นเพียงแค่เรียก __str__ กรณีที่ชัดเจนที่สุดที่ไม่เป็นความจริงเป็นสตริงตัวเอง: STR ( 'StackOverflow') ผลตอบแทนstackoverflowแต่ Repr ( 'StackOverflow') 'stackoverflow'เป็น
MatrixFrog

6
คุณมีการถอยหลัง __repr__ ไม่เคยใช้ __str__ แต่สิ่งที่ตรงกันข้ามอาจเกิดขึ้นได้ ดูdocs.python.org/reference/…

ทุกคลาสใช้ repr ใน python หรือไม่
Charlie Parker

14

__repr__ถูกใช้โดยตัวแปล Python แบบสแตนด์อโลนเพื่อแสดงคลาสในรูปแบบที่พิมพ์ได้ ตัวอย่าง:

~> 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__>

ในกรณีที่__str__ไม่ได้กำหนดเมธอดในคลาสจะเรียกใช้__repr__ฟังก์ชันนี้เพื่อพยายามสร้างการแทนค่าที่พิมพ์ได้

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

นอกจากนี้print()ในชั้นเรียนจะเรียก__str__ตามค่าเริ่มต้น


เอกสารถ้าคุณกรุณา



1

ตัวอย่างเพื่อดูความแตกต่างระหว่างพวกเขา (ฉันคัดลอกมาจากแหล่งข้อมูลนี้ )

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

ผลตอบแทนของrepr()และstr()เป็นเหมือนกันสำหรับint xแต่มีความแตกต่างระหว่างค่าผลตอบแทนสำหรับstr y- หนึ่งอย่างเป็นทางการและอื่น ๆ ที่เป็นทางการ ความแตกต่างที่สำคัญที่สุดอย่างหนึ่งระหว่างการแสดงที่เป็นทางการและไม่เป็นทางการคือการใช้งานเริ่มต้น__repr__สำหรับค่า str สามารถเรียกได้ว่าเป็นอาร์กิวเมนต์สำหรับ eval และค่าที่ส่งคืนจะเป็นอ็อบเจ็กต์สตริงที่ถูกต้องดังนี้:

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

หากคุณพยายามเรียกค่าที่ส่งคืนของ__str__เป็นอาร์กิวเมนต์เพื่อประเมินผลลัพธ์จะไม่ถูกต้อง


1

เมื่อเราสร้างประเภทใหม่โดยกำหนดคลาสเราสามารถใช้ประโยชน์จากคุณสมบัติบางอย่างของ Python เพื่อทำให้คลาสใหม่ใช้งานได้สะดวก หนึ่งในคุณสมบัติเหล่านี้คือ "วิธีพิเศษ" หรือที่เรียกว่า "วิธีวิเศษ"

วิธีการพิเศษมีชื่อที่ขึ้นต้นและลงท้ายด้วยเครื่องหมายขีดล่างสองตัว เราให้คำจำกัดความ แต่มักไม่เรียกชื่อโดยตรง แต่จะดำเนินการโดยอัตโนมัติภายใต้สถานการณ์เฉพาะ

สะดวกที่จะสามารถส่งออกค่าของอินสแตนซ์ของวัตถุโดยใช้คำสั่งพิมพ์ เมื่อเราทำเช่นนี้เราต้องการให้ค่าแสดงในผลลัพธ์ในรูปแบบที่เข้าใจได้ไม่ชัดเจน Reprวิธีพิเศษสามารถใช้ในการเตรียมการสำหรับการนี้จะเกิดขึ้น หากเรากำหนดวิธีการนี้สามารถเรียกใช้โดยอัตโนมัติเมื่อเราพิมพ์ค่าของอินสแตนซ์ของคลาสที่เรากำหนดเมธอดนี้ อย่างไรก็ตามควรกล่าวถึงว่ายังมีวิธีพิเศษของstrซึ่งใช้สำหรับวัตถุประสงค์ที่คล้ายกัน แต่ไม่เหมือนกันซึ่งอาจมีความสำคัญกว่าหากเราได้กำหนดไว้ด้วย

หากเราไม่ได้กำหนดวิธีการreprสำหรับคลาส Point3D และสร้างอินสแตนซ์ my_point เป็นอินสแตนซ์ของ Point3D จากนั้นเราจะทำสิ่งนี้ ...

พิมพ์ my_point ... เราอาจเห็นสิ่งนี้เป็นผลลัพธ์ ...

ไม่ค่อยดีใช่มั้ย?

ดังนั้นเราจึงกำหนดเมธอดพิเศษreprหรือstrหรือทั้งสองอย่างเพื่อให้ได้ผลลัพธ์ที่ดีขึ้น

**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**

เอาท์พุต ...

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


1

ใช้reprสำหรับทุกคลาสที่คุณใช้ ไม่ควรมีข้ออ้างใด ๆ ใช้strสำหรับชั้นเรียนที่คุณคิดว่าการอ่านง่ายมีความสำคัญมากกว่าสำหรับความไม่คลุมเครือ

โปรดดูที่ลิงค์นี้: https://www.pythoncentral.io/what-is-the-difference-between- STRโทโพโลยีRepr -in-หลาม /

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.