__Str__ और __repr__ के बीच अंतर?


जवाबों:


2723

एलेक्स ने अच्छी तरह से संक्षेप में कहा, लेकिन आश्चर्यजनक रूप से, बहुत ही संक्षिप्त था।

सबसे पहले, मैं एलेक्स के पोस्ट में मुख्य बिंदुओं को दोहराता हूं :

  • डिफ़ॉल्ट कार्यान्वयन बेकार है (यह सोचना मुश्किल है कि कौन सा नहीं होगा, लेकिन हाँ)
  • __repr__ लक्ष्य असंदिग्ध होना है
  • __str__ लक्ष्य पठनीय होना है
  • कंटेनर के __str__उपयोग में निहित वस्तुएँ हैं '__repr__

डिफ़ॉल्ट कार्यान्वयन बेकार है

यह ज्यादातर एक आश्चर्य की बात है क्योंकि पायथन की चूक काफी उपयोगी होती है। हालाँकि, इस मामले में, जिसके लिए कोई डिफ़ॉल्ट __repr__कार्य करेगा:

return "%s(%r)" % (self.__class__, self.__dict__)

बहुत खतरनाक होता (उदाहरण के लिए, अनंत पुनरावर्तन में प्राप्त करना बहुत आसान होता है यदि ऑब्जेक्ट एक दूसरे को संदर्भित करते हैं)। तो पायथन बाहर हो जाता है। ध्यान दें कि एक डिफ़ॉल्ट है जो सत्य है: यदि __repr__परिभाषित किया गया है, और __str__नहीं है, तो वस्तु हालांकि व्यवहार करेगी __str__=__repr__

इसका मतलब है, सरल शब्दों में: आपके द्वारा लागू की जाने वाली लगभग हर वस्तु में एक कार्यात्मक होना चाहिए जो __repr__वस्तु को समझने के लिए उपयोग करने योग्य हो। लागू __str__करना वैकल्पिक है: यदि आपको "सुंदर प्रिंट" कार्यक्षमता की आवश्यकता है (उदाहरण के लिए, रिपोर्ट जनरेटर द्वारा उपयोग किया जाता है)।

का लक्ष्य __repr__असंदिग्ध होना है

मुझे ठीक से आने दो और कहो - मुझे डिबगर्स पर विश्वास नहीं है। मैं वास्तव में किसी डिबगर का उपयोग करना नहीं जानता, और कभी भी किसी ने गंभीरता से उपयोग नहीं किया। इसके अलावा, मेरा मानना ​​है कि डीबगर्स में बड़ी गलती उनकी मूल प्रकृति है - सबसे अधिक विफलताएं जो मैंने डिबग की थी वह बहुत पहले एक आकाशगंगा में दूर दूर तक हुई थी। इसका मतलब यह है कि मुझे विश्वास है, धार्मिक उत्साह के साथ, लॉगिंग में। लॉगिंग किसी भी सभ्य आग और भूल सर्वर प्रणाली का जीवन है। पायथन को लॉग इन करना आसान बनाता है: हो सकता है कि कुछ प्रोजेक्ट विशिष्ट रैपर के साथ, आपको बस एक की आवश्यकता हो

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

लेकिन आपको अंतिम चरण करना होगा - सुनिश्चित करें कि आपके द्वारा लागू की जाने वाली प्रत्येक वस्तु में एक उपयोगी रीप्र है, इसलिए जैसे कोड बस काम कर सकते हैं। यही कारण है कि "स्पष्ट" बात सामने आती है: यदि आपके पास पर्याप्त जानकारी है eval(repr(c))==c, तो इसका मतलब है कि आप जानते हैं कि सब कुछ पता है c। यदि यह काफी आसान है, कम से कम एक फजी तरीके से, यह करो। यदि नहीं, तो सुनिश्चित करें कि आपके पास cवैसे भी पर्याप्त जानकारी है। मैं आमतौर पर एक eval- जैसे प्रारूप का उपयोग करता हूं "MyClass(this=%r,that=%r)" % (self.this,self.that):। इसका मतलब यह नहीं है कि आप वास्तव में MyClass का निर्माण कर सकते हैं, या यह कि वे सही रचनाकार तर्क हैं - लेकिन यह "इस उदाहरण के बारे में आपको जानने की आवश्यकता है" यह व्यक्त करने के लिए एक उपयोगी रूप है।

नोट: मैंने %rऊपर प्रयोग किया है, नहीं %s। आप हमेशा कार्यान्वयन के अंदर repr()[ %r, समतुल्य रूप से] चरित्र का उपयोग करना चाहते हैं __repr__, या आप repr के लक्ष्य को हरा रहे हैं। आप अंतर करने में सक्षम होना चाहते हैं MyClass(3)और MyClass("3")

का लक्ष्य __str__पठनीय होना है

विशेष रूप से, यह अस्पष्ट होने का इरादा नहीं है - ध्यान दें कि str(3)==str("3")। इसी तरह, यदि आप एक आईपी अमूर्त को लागू करते हैं, तो उसमें से 192.168.1.1 जैसा दिखना ठीक है। एक तिथि / समय अमूर्त को लागू करते समय, str "2010/4/12 15:35:22", आदि हो सकता है। लक्ष्य यह है कि इसे इस तरह से दर्शाया जाए कि एक उपयोगकर्ता, न कि एक प्रोग्रामर, इसे पढ़ना चाहेगा। बेकार अंकों को काट दें, कुछ अन्य वर्ग होने का दिखावा करें - जब तक यह पठनीयता का समर्थन करता है, यह एक सुधार है।

कंटेनर के __str__उपयोग में निहित वस्तुएँ हैं '__repr__

यह आश्चर्यजनक लगता है, है ना? यह एक छोटा सा है, लेकिन यह कितना पठनीय होगा यदि यह उनका उपयोग करता है __str__?

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

बहुत नहीं। विशेष रूप से, एक कंटेनर में तार अपने स्ट्रिंग प्रतिनिधित्व को परेशान करने के लिए बहुत आसान होगा। अस्पष्टता के सामने, याद रखें, पायथन अनुमान लगाने के प्रलोभन का विरोध करता है। यदि आप किसी सूची को मुद्रित करते समय उपरोक्त व्यवहार चाहते हैं, तो बस

print "[" + ", ".join(l) + "]"

(आप शायद यह भी पता लगा सकते हैं कि शब्दकोशों के बारे में क्या करना है।

सारांश

आपके द्वारा कार्यान्वित __repr__किसी भी वर्ग के लिए कार्यान्वयन। यह दूसरा स्वभाव होना चाहिए। लागू करें __str__यदि आपको लगता है कि यह एक स्ट्रिंग संस्करण के लिए उपयोगी होगा जो पठनीयता के पक्ष में है।


153
निश्चित रूप से आपकी राय से असहमत हैं कि डिबगिंग जाने का रास्ता नहीं है। उत्पादन उपयोग लॉगिंग के लिए विकास के लिए डिबगर (और / या लॉगिंग) का उपयोग करें। डिबगर के साथ आपके पास हर उस चीज़ का एक दृश्य है जो समस्या होने पर गलत हो गया था। आप पूरी तस्वीर देख सकते हैं। जब तक आप हर बार लॉग इन नहीं कर रहे हैं तब तक आप उसे प्राप्त नहीं कर सकते। इसके अलावा अगर आप सब कुछ लॉग कर रहे हैं, तो आपको जो भी चाहिए उस डेटा को प्राप्त करने के लिए टोंड के माध्यम से उतारा जाना चाहिए।
शमूएल

20
महान उत्तर (डिबगर्स का उपयोग नहीं करने के बारे में थोड़ा छोड़कर)। मैं केवल इस अन्य क्यू एंड ए के बारे में एक लिंक जोड़ना चाहूंगा जो कि पायथन 3 में str बनाम यूनिकोड के बारे में है, जो उन लोगों के लिए चर्चा के लिए प्रासंगिक हो सकता है जिन्होंने स्विच किया है।
ThatAintWorking

11
डीबगर्स के लिए प्लस 1 बेकार हैं, और एक पैसा भी नहीं है। इसके बजाय अपने लॉगिंग थ्रूपुट प्राप्त करें। और हाँ यह एक अच्छी तरह से लिखा गया पोस्ट था। यह बताता है __repr__कि मुझे डिबगिंग के लिए क्या चाहिए था। आपके सहयोग के लिए धन्यवाद।
व्यक्तिगत_क्लाउड

7
आपके डिबगर ने एक तरफ मूर्खता की, मैंने% r सीखा और यह वैसे भी वोट के लायक है
मिकी पर्लस्टीन डे

6
डिबगर बनाम कोई डिबगर पर: ऐसी उलझी हुई राय नहीं मिलती। कुछ अनुप्रयोगों में डिबगिंग यथार्थवादी नहीं है, आमतौर पर जब वास्तविक समय शामिल होता है, या जब आपका कोड केवल एक प्लेटफॉर्म पर दूरस्थ रूप से निष्पादित होता है जिसमें थोड़ी पहुंच या कोई कंसोल नहीं होता है। अधिकांश अन्य मामलों में जांच करने के लिए, या ब्रेकपॉइंट सेट करने के लिए एक अपवाद को रोकने के लिए यह बहुत तेज होगा, क्योंकि आपको लॉगिंग की हजारों लाइनों से गुजरना नहीं है (जो आपकी डिस्क को अव्यवस्थित कर देगा और एप्लिकेशन को धीमा कर देगा)। अंत में, लॉग इन करना हमेशा संभव नहीं होता है, उदाहरण के लिए एम्बेडेड डिवाइस पर, डिबगर आपका मित्र भी है।
RedGlyph

523

मेरे अंगूठे का नियम: __repr__डेवलपर्स के लिए है, __str__ग्राहकों के लिए है।


2
यह सही है क्योंकि obj = uuid.uuid1 (), obj .__ str __ () के लिए "2d7fc7f0-7706-11e9-94ae-0242ac1100022 और obj .__ repr __ ()" UUID ('2d7fc7f7-7.17.17.17-7.17) है। ') "। डेवलपर्स को मूल्य (मूल +) की आवश्यकता होती है जबकि ग्राहकों को एक मूल्य की आवश्यकता होती है और वे परवाह नहीं करते हैं कि उन्हें यह कैसे मिला!
नरेन येलावुला

1
यहां ग्राहक को अंत उपयोगकर्ता का मतलब नहीं हो सकता है। यह ऑब्जेक्ट का क्लाइंट या उपयोगकर्ता है। इसलिए यदि इसका SDK है तो SDK डेवलपर्स का उपयोग करेगा __str__ताकि सामान्य डेवलपर्स के पास पठनीय वस्तु हो। दूसरी ओर, __repr__खुद एसडीके डेवलपर्स के लिए है।
शिप्पू मोकादिम

398

जब तक आप विशेष रूप से अन्यथा सुनिश्चित करने के लिए कार्य नहीं करते हैं, तब तक अधिकांश वर्गों के पास सहायक परिणाम नहीं हैं:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

जैसा कि आप देखते हैं - कोई अंतर नहीं है, और वर्ग और वस्तु से परे कोई जानकारी नहीं है id। यदि आप केवल दो में से एक को ओवरराइड करते हैं ...:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

जैसा कि आप देखते हैं, यदि आप ओवरराइड करते हैं, तो __repr__यह भी इसके लिए उपयोग किया जाता है __str__, लेकिन इसके विपरीत नहीं।

अन्य महत्वपूर्ण tidbits पता करने के लिए: __str__एक अंतर्निर्मित कंटेनर पर , इसमें शामिल वस्तुओं के लिए __repr__, नहीं, का उपयोग करता है __str__। और, विशिष्ट डॉक्स में पाए जाने वाले विषय पर शब्दों के बावजूद, __repr__वस्तुओं को बनाने वाले शायद ही कोई परेशान करता है , जो evalएक समान वस्तु का निर्माण करने के लिए उपयोग कर सकता है (यह सिर्फ बहुत कठिन है, और यह नहीं जानना कि संबंधित मॉड्यूल वास्तव में कैसे आयात किया गया था, यह वास्तव में बनाता है फ्लैट बाहर असंभव)।

इसलिए, मेरी सलाह: __str__यथोचित मानव-पठनीय बनाने पर ध्यान केंद्रित करें , और __repr__जितना संभव हो सके उतना अस्पष्ट, भले ही वह __repr__इनपुट के रूप में स्वीकार्य मान को लौटाने के फ़र्ज़ी अप्राप्य लक्ष्य के साथ हस्तक्षेप करता हो __eval__!


34
मेरी इकाई परीक्षणों में मैं हमेशा जाँच करता हूं कि eval(repr(foo))किसी वस्तु के बराबर मूल्यांकन करता है foo। आप सही हैं कि यह मेरे परीक्षण मामलों के बाहर काम नहीं करेगा क्योंकि मुझे नहीं पता कि मॉड्यूल कैसे आयात किया जाता है, लेकिन यह कम से कम यह सुनिश्चित करता है कि यह कुछ अनुमानित संदर्भ में काम करता है । मुझे लगता है कि मूल्यांकन का यह एक अच्छा तरीका है यदि परिणाम __repr__पर्याप्त स्पष्ट है। एक इकाई परीक्षण में ऐसा करने से यह सुनिश्चित करने में भी मदद मिलती है कि __repr__कक्षा में परिवर्तन इस प्रकार है।
स्टीवन टी। स्नाइडर

4
मैं हमेशा यह सुनिश्चित करने की कोशिश करता हूं कि या तो eval(repr(spam)) == spam(कम से कम सही संदर्भ में), या eval(repr(spam))उठे SyntaxError। इस तरह आप भ्रम से बच जाते हैं। (और यह बिल्टइन और ज्यादातर stdlib के लिए लगभग सच है, इसके अलावा, उदाहरण के लिए, पुनरावर्ती सूचियाँ, जहाँ a=[]; a.append(a); print(eval(repr(a)))आपको देता है [[Ellipses]]...) बेशक मैं वास्तव में उपयोग करने के लिए ऐसा नहीं करता eval(repr(spam)), सिवाय इकाई परीक्षणों में एक पवित्रता जाँच के ... लेकिन मैं है कभी कभी कॉपी और पेस्ट repr(spam)एक इंटरैक्टिव सत्र में।
अपराह्न

__str__इसके बजाय प्रत्येक तत्व के लिए कंटेनरों (सूचियों, टुपल्स) का उपयोग क्यों नहीं किया जाएगा __repr__? यह मेरे लिए गलत लगता है, क्योंकि मैंने __str__अपनी वस्तु में एक पठनीय लागू किया है और जब यह एक सूची का हिस्सा होता है तो मैं __repr__इसके बजाय बदसूरत देखता हूं ।
सुपरगो

बस इस तथ्य से संबंधित एक कष्टप्रद बग में भाग गया, जो eval(repr(x))बिलिन के प्रकारों के लिए भी विफल रहता है: class A(str, Enum): X = 'x'सिंटेक्सएर्र पर उठाएंगे eval(repr(A.X))। यह दुखद है, लेकिन समझने योग्य है। BTW, eval(str(A.X))वास्तव में काम करता है, लेकिन निश्चित रूप से केवल अगर class Aगुंजाइश है - तो यह शायद बहुत उपयोगी नहीं है।
अधिकतम

@SuperGeo अन्य उत्तर इस कवर: कंटेनर strउपयोग तत्व reprक्योंकि [1, 2, 3]=! ["1", "2, 3"]
मृत्युंजय

163

__repr__: आमतौर पर eval अजगर वस्तु का प्रतिनिधित्व इसे वापस उस वस्तु में बदल देगा

__str__: जो कुछ भी आप सोचते हैं, वह वस्तु पाठ रूप में है

जैसे

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

151

संक्षेप में, का लक्ष्य __repr__असंदिग्ध होना है और __str__पठनीय होना है।

यहाँ एक अच्छा उदाहरण है:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

इस दस्तावेज़ को repr के लिए पढ़ें:

repr(object)

किसी ऑब्जेक्ट के मुद्रण योग्य प्रतिनिधित्व वाले स्ट्रिंग को लौटाएं। यह रूपांतरणों (रिवर्स कोट्स) द्वारा प्राप्त समान मूल्य है। कभी-कभी एक साधारण फ़ंक्शन के रूप में इस ऑपरेशन तक पहुंचने में सक्षम होना उपयोगी होता है। कई प्रकारों के लिए, यह फ़ंक्शन एक स्ट्रिंग को वापस करने का प्रयास करता है, जो पास होने पर उसी मूल्य के साथ एक वस्तु प्राप्त करेगा eval(), अन्यथा प्रतिनिधित्व कोण कोष्ठक में संलग्न एक स्ट्रिंग है जिसमें अतिरिक्त जानकारी के साथ ऑब्जेक्ट के प्रकार का नाम शामिल है अक्सर वस्तु का नाम और पता सहित। एक वर्ग इस बात को नियंत्रित कर सकता है कि यह फ़ंक्शन किस __repr__()विधि को परिभाषित करके अपने उदाहरणों के लिए वापस लौटता है ।

यहाँ str के लिए प्रलेखन है:

str(object='')

किसी वस्तु की अच्छी तरह से मुद्रण योग्य प्रतिनिधित्व युक्त स्ट्रिंग लौटें। स्ट्रिंग्स के लिए, यह स्ट्रिंग को स्वयं लौटाता है। इसके साथ अंतर repr(object)यह है कि str(object)हमेशा एक स्ट्रिंग वापस करने का प्रयास नहीं करता है जो स्वीकार्य है eval(); इसका लक्ष्य एक मुद्रण योग्य स्ट्रिंग वापस करना है। कोई तर्क दिया जाता है, तो, खाली स्ट्रिंग रिटर्न ''


1
यहाँ प्रिंट करने योग्य स्ट्रिंग का अर्थ क्या है? क्या आप कृपया इसे समझा सकते हैं?
विक्रोबोट

115

पायथन में __str__और क्या अंतर है __repr__?

__str__("डंडर (डबल-अंडरस्कोर) स्ट्रिंग" के __repr__रूप में पढ़ें ) और ("डंडर-रीपर" ("प्रतिनिधित्व" के लिए) के रूप में पढ़ें) दोनों विशेष तरीके हैं जो वस्तु की स्थिति के आधार पर तार लौटाते हैं।

__repr____str__अनुपलब्ध होने पर बैकअप व्यवहार प्रदान करता है।

तो पहले एक लिखना चाहिए __repr__जो आपको स्ट्रिंग से एक समतुल्य वस्तु को पुनः प्राप्त करने की अनुमति देता है जैसे कि यह एक उदाहरण के रूप में देता है evalया इसे पायथन शेल में चरित्र-के-चरित्र में टाइप करके।

किसी भी समय बाद में, कोई __str__उदाहरण के उपयोगकर्ता-पठनीय स्ट्रिंग प्रतिनिधित्व के लिए लिख सकता है , जब कोई मानता है कि यह आवश्यक है।

__str__

आप किसी ऑब्जेक्ट प्रिंट, या यह पार कर लेते हैं करने के लिए format, str.formatया str, तो अगर एक __str__विधि परिभाषित किया गया है, उस विधि बुलाया जाएगा, अन्यथा, __repr__इस्तेमाल किया जाएगा।

__repr__

__repr__विधि builtin समारोह से पुकारा जाता है reprऔर क्या आपके अजगर खोल पर गूँजती है जब यह एक अभिव्यक्ति है कि एक वस्तु रिटर्न का मूल्यांकन करता है।

चूंकि यह एक बैकअप प्रदान करता है __str__, यदि आप केवल एक ही लिख सकते हैं, तो शुरू करें__repr__

यहाँ पर अंतर्निहित मदद है repr:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

यही है, अधिकांश वस्तुओं के लिए, यदि आप जो कुछ मुद्रित करते हैं repr, उसमें टाइप करते हैं, तो आपको एक समतुल्य वस्तु बनाने में सक्षम होना चाहिए। लेकिन यह डिफ़ॉल्ट कार्यान्वयन नहीं है।

का डिफ़ॉल्ट कार्यान्वयन __repr__

डिफ़ॉल्ट वस्तु __repr__( सी पायथन स्रोत ) कुछ इस तरह है:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

इसका मतलब है कि डिफ़ॉल्ट रूप से आप उस मॉड्यूल को प्रिंट करेंगे जो ऑब्जेक्ट क्लास के नाम से है, और स्मृति में इसके स्थान का हेक्साडेसिमल प्रतिनिधित्व - उदाहरण के लिए:

<__main__.Foo object at 0x7f80665abdd0>

यह जानकारी बहुत उपयोगी नहीं है, लेकिन इसका कोई तरीका नहीं है कि किसी भी दिए गए उदाहरण का एक कैनोनिकल प्रतिनिधित्व कैसे सही तरीके से किया जा सकता है, और यह कुछ भी नहीं से बेहतर है, कम से कम हमें बताए कि हम इसे कैसे विशिष्ट रूप से स्मृति में पहचान सकते हैं।

कैसे __repr__उपयोगी हो सकता है?

आइए देखें कि पायथन शेल और datetimeऑब्जेक्ट्स का उपयोग करके यह कितना उपयोगी हो सकता है । पहले हमें datetimeमॉड्यूल आयात करने की आवश्यकता है :

import datetime

यदि हम datetime.nowशेल में कॉल करते हैं, तो हम एक समतुल्य डेटाटाइम ऑब्जेक्ट को पुनः बनाने के लिए आवश्यक सभी चीज़ों को देखेंगे। यह डेटाटाइम द्वारा बनाया गया है __repr__:

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

यदि हम एक डेटाटाइम ऑब्जेक्ट प्रिंट करते हैं, तो हम एक अच्छा मानव पठनीय (वास्तव में, आईएसओ) प्रारूप देखते हैं। यह डेटाटाइम द्वारा कार्यान्वित किया गया है __str__:

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

हमने खोई हुई वस्तु को फिर से बनाना एक साधारण मामला है क्योंकि हमने इसे __repr__आउटपुट से कॉपी और पेस्ट करके एक चर को नहीं सौंपा है , और फिर इसे प्रिंट किया है, और हम इसे अन्य ऑब्जेक्ट के समान मानव पठनीय आउटपुट में प्राप्त करते हैं:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

मैं उन्हें कैसे लागू करूं?

जैसा कि आप विकसित कर रहे हैं, आप चाहें तो उसी स्थिति में वस्तुओं को पुन: उत्पन्न करने में सक्षम हो सकते हैं। यह, उदाहरण के लिए, कैसे डेटाटाइम ऑब्जेक्ट परिभाषित करता है __repr__( पायथन स्रोत )। यह काफी जटिल है, क्योंकि इस तरह के ऑब्जेक्ट को पुन: पेश करने के लिए आवश्यक सभी विशेषताओं के कारण:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

यदि आप चाहते हैं कि आपकी वस्तु अधिक मानवीय पठनीय प्रतिनिधित्व करे, तो आप __str__अगले को लागू कर सकते हैं । यहां बताया गया है कि कैसे डेटाटाइम ऑब्जेक्ट ( पायथन स्रोत ) लागू होता है __str__, जो इसे आसानी से करता है क्योंकि यह पहले से ही आईएसओ प्रारूप में इसे प्रदर्शित करने के लिए एक फ़ंक्शन है

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

सेट करें __repr__ = __str__?

यह यहां एक और उत्तर की आलोचना है जो सेटिंग का सुझाव देता है __repr__ = __str__

सेटिंग __repr__ = __str__मूर्खतापूर्ण है - डिबगिंग में डेवलपर्स उपयोग के लिए लिखा गया एक और के __repr__लिए एक कमबैक __str__है __repr__, आपको लिखने से पहले लिखा जाना चाहिए __str__

आपको __str__केवल उसी समय की आवश्यकता होती है जब आपको ऑब्जेक्ट के एक पाठीय प्रतिनिधित्व की आवश्यकता होती है।

निष्कर्ष

__repr__आपके द्वारा लिखी जाने वाली वस्तुओं के लिए परिभाषित करें ताकि आप और अन्य डेवलपर्स का विकास करते समय इसका उपयोग करने के लिए एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण हो। परिभाषित करें __str__जब आपको मानव पठनीय स्ट्रिंग प्रतिनिधित्व की आवश्यकता हो।


यह की तर्ज पर कुछ नहीं होना चाहिए type(obj).__qualname__?
सुलैमान उको

पायथन 3 में @SolomonUcko हां, यह मामला प्रतीत होता है - मैं स्रोत कोड का शिकार कर रहा हूं जहां इसे लागू किया गया है और जब मैं इसे प्राप्त करता हूं, तो मैं उस जानकारी के साथ अपने उत्तर को अपडेट करूंगा।
हारून हॉल

33

हंस पेटर लैंगटांगेन द्वारा कम्प्यूटेशनल साइंस के लिए पाइथन स्क्रिप्टिंग की किताब के पेज 358 पर यह स्पष्ट रूप से लिखा गया है कि:

  • __repr__वस्तु की एक पूरी स्ट्रिंग प्रतिनिधित्व करना है;
  • __str__मुद्रण के लिए एक अच्छी स्ट्रिंग वापस जाने के लिए है।

इसलिए, मैं उन्हें समझना पसंद करता हूं

  • repr = पुन: पेश
  • str = string (प्रतिनिधित्व)

उपयोगकर्ता के दृष्टिकोण से हालांकि यह एक गलतफहमी है कि मैंने अजगर को सीखते समय बनाया था।

एक छोटा लेकिन अच्छा उदाहरण भी इस प्रकार दिया गया है:

उदाहरण

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

यह पीजी पर है। # 351।
जितेन

4
यह reprपुन: पेश करने के लिए संदर्भित करने के लिए भ्रामक है । इसे प्रतिनिधित्व के रूप में सोचना बेहतर है।
नेल्सनगॉन

31

दिए गए सभी उत्तरों के अलावा, मैं कुछ बिंदुओं को जोड़ना चाहूंगा: -

1) __repr__()का उपयोग तब किया जाता है जब आप केवल इंटरेक्टिव पाइथन कंसोल पर ऑब्जेक्ट का नाम लिखते हैं और एंटर दबाते हैं।

2) __str__()जब आप प्रिंट स्टेटमेंट के साथ ऑब्जेक्ट का उपयोग करते हैं, तो उसे लागू किया जाता है।

3) यदि __str__कोई str()चीज गायब है, तो __repr__()ऑब्जेक्ट के इनवोक का उपयोग करके प्रिंट करें और कोई भी फ़ंक्शन ।

4) __str__()कंटेनरों का, जब आह्वान __repr__()इसके निहित तत्वों की विधि को निष्पादित करेगा ।

5) के str()भीतर बुलाया __str__()बेस मामले के बिना संभावित रूप से पुनरावृत्ति कर सकता है, और अधिकतम पुनरावृत्ति गहराई पर त्रुटि हो सकती है।

6) __repr__()कॉल कर सकते हैं repr()जो पहले से प्रतिनिधित्व वाली वस्तु की जगह, स्वचालित रूप से अनंत पुनरावृत्ति से बचने का प्रयास करेगा ...


13

सभी ईमानदारी में, eval(repr(obj))कभी भी उपयोग नहीं किया जाता है। यदि आप इसका उपयोग करते हुए खुद को पाते हैं, तो आपको रोकना चाहिए, क्योंकि evalखतरनाक है, और तार अपनी वस्तुओं को क्रमबद्ध करने के लिए एक बहुत ही अक्षम तरीका है ( pickleइसके बजाय उपयोग करें )।

इसलिए, मैं सेटिंग की सिफारिश करूंगा __repr__ = __str__। कारण यह है कि तत्वों पर str(list)कॉल repr(मैं इसे पायथन के सबसे बड़े डिजाइन दोषों में से एक मानता हूं जिसे पायथन 3 द्वारा संबोधित नहीं किया गया था)। एक वास्तविक reprशायद के उत्पादन के रूप में बहुत उपयोगी नहीं होगा print [your, objects]

इसे योग्य बनाने के लिए, मेरे अनुभव में, reprफ़ंक्शन का सबसे उपयोगी उपयोग एक स्ट्रिंग को दूसरे स्ट्रिंग के अंदर रखना है (स्ट्रिंग स्वरूपण का उपयोग करके)। इस तरह, आपको उद्धरण या कुछ भी बचने के बारे में चिंता करने की ज़रूरत नहीं है। लेकिन ध्यान दें कि यहां कुछ भी नहीं evalहो रहा है।


19
मुझे लगता है कि यह बात याद आती है। का उपयोग eval(repr(obj))एक पवित्रता परीक्षण और अंगूठे का एक नियम है - यदि यह मूल वस्तु को सही ढंग से फिर से बनाता है तो आपके पास एक अच्छा __repr__कार्यान्वयन है। यह इरादा नहीं है कि आप वास्तव में इस तरह से वस्तुओं को क्रमबद्ध करते हैं।
jwg

7
evalस्वाभाविक रूप से खतरनाक नहीं है। से भी ज्यादा खतरनाक नहीं है unlink, openया वे फ़ाइलें लेखन। क्या हमें फाइलों को लिखना बंद कर देना चाहिए क्योंकि शायद कोई दुर्भावनापूर्ण हमला सामग्री को अंदर डालने के लिए एक मनमाना फ़ाइल पथ का उपयोग कर सकता है? सब कुछ खतरनाक है अगर गूंगा लोगों द्वारा विनम्रता से उपयोग किया जाता है। मुहावरा खतरनाक है। धूर्त-क्रुगर प्रभाव खतरनाक हैं। evalसिर्फ एक फंक्शन है।
लुइस मासुइली

13

अगर सरल शब्द में कहा जाए तो:

__str__दूसरों द्वारा आसानी से पढ़े जाने के लिए अपनी वस्तु का एक स्ट्रिंग प्रतिनिधित्व दिखाने के लिए उपयोग किया जाता है ।

__repr__के एक स्ट्रिंग प्रतिनिधित्व को दिखाने के लिए प्रयोग किया जाता है वस्तु।

मान लीजिए कि मैं एक ऐसी Fractionकक्षा बनाना चाहता हूँ जहाँ एक अंश का स्ट्रिंग निरूपण '(1/2)' और वस्तु (अंश वर्ग) को 'भिन्न (1,2)' के रूप में प्रस्तुत करना है।

तो हम एक साधारण फ्रैक्शन क्लास बना सकते हैं:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

12

से एक (एक अनौपचारिक) अजगर संदर्भ विकी (संग्रह कॉपी) effbot द्वारा:

__str__" किसी वस्तु के" अनौपचारिक "स्ट्रिंग प्रतिनिधित्व की गणना करता है। यह इस बात से अलग __repr__है कि इसमें एक वैध पायथन अभिव्यक्ति होना जरूरी नहीं है: इसके बजाय अधिक सुविधाजनक या संक्षिप्त प्रतिनिधित्व का उपयोग किया जा सकता है। "


3
__repr__एक vaild पायथन अभिव्यक्ति को वापस करने के लिए किसी भी तरह की आवश्यकता नहीं है।
मैड

10

str - दिए गए ऑब्जेक्ट से एक नया स्ट्रिंग ऑब्जेक्ट बनाता है।

repr - वस्तु का कैनोनिकल स्ट्रिंग प्रतिनिधित्व लौटाता है।

अंतर:

str ():

  • वस्तु को पठनीय बनाता है
  • एंड-यूज़र के लिए आउटपुट जेनरेट करता है

रेपर ():

  • कोड की जरूरत है जो वस्तु को पुन: पेश करता है
  • डेवलपर के लिए आउटपुट उत्पन्न करता है

8

एक पहलू जो अन्य उत्तरों में गायब है। यह सच है कि सामान्य तौर पर पैटर्न है:

  • लक्ष्य __str__: मानव-पठनीय
  • लक्ष्य __repr__: असंदिग्ध, संभवतः मशीन के माध्यम से पठनीयeval

दुर्भाग्य से, यह भेदभाव त्रुटिपूर्ण है, क्योंकि __repr__एक REPL कंसोल में पायथन आरईपीएल और आईपीथॉन वस्तुओं को प्रिंट करने के लिए भी उपयोग करता है ( पायथन और आईपीथॉन के लिए संबंधित प्रश्न देखें )। इस प्रकार, परियोजनाओं को इंटरेक्टिव कंसोल काम के लिए लक्षित किया जाता है (उदाहरण के लिए, नम्पी या पंडों) ने नियमों को अनदेखा करना शुरू कर दिया है और __repr__इसके बजाय मानव-पठनीय कार्यान्वयन प्रदान करते हैं ।


7

पुस्तक धाराप्रवाह पायथन से :

पायथन ऑब्जेक्ट के लिए एक बुनियादी आवश्यकता स्वयं के उपयोग करने योग्य स्ट्रिंग अभ्यावेदन प्रदान करना है, एक डीबगिंग और लॉगिंग के लिए उपयोग किया जाता है, दूसरा उपयोगकर्ताओं को प्रस्तुति के लिए प्रस्तुति के लिए। यही कारण है कि डेटा मॉडल में
विशेष तरीके __repr__और __str__मौजूद हैं।


5

बहुत बढ़िया जवाब पहले से ही बीच के अंतर को कवर __str__और __repr__डेवलपर्स के लिए यथासंभव उपयोगी है, जो मेरे लिए पठनीय भी एक अंत उपयोगकर्ता द्वारा पूर्व से किया जा रहा करने पर निर्भर करता है, और बाद किया जा रहा है। यह देखते हुए, मुझे पता है कि __repr__अक्सर डिफ़ॉल्ट लक्ष्य इस लक्ष्य को प्राप्त करने में विफल रहता है क्योंकि यह डेवलपर्स के लिए उपयोगी जानकारी को छोड़ देता है।

इस कारण से, यदि मेरे पास एक सरल पर्याप्त है __str__, तो मैं आमतौर पर दोनों दुनिया के सर्वश्रेष्ठ को कुछ इस तरह से प्राप्त करने की कोशिश करता हूं:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

4

ध्यान रखने वाली एक महत्वपूर्ण बात यह है कि कंटेनर में __str__निहित वस्तुएं हैं __repr__

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

पाइथन पठनीयता , __str__एक tupleकॉल समाहित वस्तुओं ' __repr__, एक वस्तु के "औपचारिक" प्रतिनिधित्व पर असंदिग्धता का पक्षधर है । यद्यपि औपचारिक प्रतिनिधित्व एक अनौपचारिक से पढ़ने के लिए कठिन है, यह असंदिग्ध है और बग के खिलाफ अधिक मजबूत है।


इसका उपयोग __repr__ तब होता है जब यह ( __str__) परिभाषित नहीं होता है! तो, आप गलत हैं।
जितेन

4

संक्षेप में:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

4
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

जब print()कॉल किया जाता है decimal.Decimal(23) / decimal.Decimal("1.05")तो कच्चे नंबर के परिणाम को प्रिंट किया जाता है; यह आउटपुट स्ट्रिंग रूप में है जिसे हासिल किया जा सकता है __str__()। यदि हम बस अभिव्यक्ति प्राप्त करते हैं तो हमें decimal.Decimalआउटपुट मिलता है - यह आउटपुट रिप्रेजेंटेटिव रूप में होता है जिसे हासिल किया जा सकता है __repr__()। सभी पायथन ऑब्जेक्ट्स के दो आउटपुट फॉर्म हैं। स्ट्रिंग फॉर्म को मानव-पठनीय बनाया गया है। प्रतिनिधित्वात्मक रूप से उत्पादन के लिए डिज़ाइन किया गया है कि अगर पायथन इंटरप्रेटर को खिलाया जाता है (जब संभव हो) प्रतिनिधित्व की गई वस्तु को पुन: उत्पन्न करता है।


4

__str__किसी वस्तु पर कॉल करके आह्वान किया जा सकता है str(obj)और उसे मानव पठनीय स्ट्रिंग वापस करना चाहिए।

__repr__कॉल करके किसी ऑब्जेक्ट पर लगाया जा सकता है repr(obj)और आंतरिक ऑब्जेक्ट (ऑब्जेक्ट फ़ील्ड / विशेषता) को वापस करना चाहिए

यह उदाहरण मदद कर सकता है:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr

3

समझ __str__और__repr__ सहज और स्थायी रूप से उन्हें अलग पहचान दें।

__str__ आँखों की पठनीयता के लिए किसी दिए गए ऑब्जेक्ट का स्ट्रिंग प्रच्छन्न शरीर लौटाएं
__repr__ वापस करना पहचानने के लिए अस्पष्टता के लिए किसी दिए गए ऑब्जेक्ट का वास्तविक मांस शरीर लौटाएं।

इसे एक उदाहरण में देखें

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

के रूप में __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

हम __repr__परिणामों पर आसानी से अंकगणितीय ऑपरेशन कर सकते हैं ।

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

यदि ऑपरेशन लागू करें __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

त्रुटि के सिवा कुछ नहीं देता।

एक और उदाहरण।

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

आशा है कि आप अधिक उत्तर तलाशने के लिए ठोस आधार बनाने में मदद करेंगे।


3
  1. __str__स्ट्रिंग ऑब्जेक्ट को वापस करना चाहिए, जबकि __repr__किसी भी अजगर अभिव्यक्ति को वापस कर सकते हैं।
  2. यदि __str__कार्यान्वयन गायब है, तो __repr__फ़ंक्शन का उपयोग फ़ॉलबैक के रूप में किया जाता है। यदि __repr__फ़ंक्शन कार्यान्वयन गायब है, तो इसमें कोई कमी नहीं है।
  3. यदि __repr__फ़ंक्शन ऑब्जेक्ट का स्ट्रिंग प्रतिनिधित्व वापस कर रहा है, तो हम __str__फ़ंक्शन के कार्यान्वयन को छोड़ सकते हैं ।

स्रोत: https://www.journaldev.com/22460/python-str-repr-functions


2

__repr__हर जगह उपयोग किया जाता है, सिवाय printऔर strतरीकों के (जब एक __str__परिभाषित किया जाता है!)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.