जवाबों:
एलेक्स ने अच्छी तरह से संक्षेप में कहा, लेकिन आश्चर्यजनक रूप से, बहुत ही संक्षिप्त था।
सबसे पहले, मैं एलेक्स के पोस्ट में मुख्य बिंदुओं को दोहराता हूं :
__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__
यदि आपको लगता है कि यह एक स्ट्रिंग संस्करण के लिए उपयोगी होगा जो पठनीयता के पक्ष में है।
__repr__
कि मुझे डिबगिंग के लिए क्या चाहिए था। आपके सहयोग के लिए धन्यवाद।
मेरे अंगूठे का नियम: __repr__
डेवलपर्स के लिए है, __str__
ग्राहकों के लिए है।
__str__
ताकि सामान्य डेवलपर्स के पास पठनीय वस्तु हो। दूसरी ओर, __repr__
खुद एसडीके डेवलपर्स के लिए है।
जब तक आप विशेष रूप से अन्यथा सुनिश्चित करने के लिए कार्य नहीं करते हैं, तब तक अधिकांश वर्गों के पास सहायक परिणाम नहीं हैं:
>>> 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__
!
eval(repr(foo))
किसी वस्तु के बराबर मूल्यांकन करता है foo
। आप सही हैं कि यह मेरे परीक्षण मामलों के बाहर काम नहीं करेगा क्योंकि मुझे नहीं पता कि मॉड्यूल कैसे आयात किया जाता है, लेकिन यह कम से कम यह सुनिश्चित करता है कि यह कुछ अनुमानित संदर्भ में काम करता है । मुझे लगता है कि मूल्यांकन का यह एक अच्छा तरीका है यदि परिणाम __repr__
पर्याप्त स्पष्ट है। एक इकाई परीक्षण में ऐसा करने से यह सुनिश्चित करने में भी मदद मिलती है कि __repr__
कक्षा में परिवर्तन इस प्रकार है।
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
गुंजाइश है - तो यह शायद बहुत उपयोगी नहीं है।
str
उपयोग तत्व repr
क्योंकि [1, 2, 3]
=! ["1", "2, 3"]
।
__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
संक्षेप में, का लक्ष्य
__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()
; इसका लक्ष्य एक मुद्रण योग्य स्ट्रिंग वापस करना है। कोई तर्क दिया जाता है, तो, खाली स्ट्रिंग रिटर्न''
।
पायथन में
__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__
?
हंस पेटर लैंगटांगेन द्वारा कम्प्यूटेशनल साइंस के लिए पाइथन स्क्रिप्टिंग की किताब के पेज 358 पर यह स्पष्ट रूप से लिखा गया है कि:
__repr__
वस्तु की एक पूरी स्ट्रिंग प्रतिनिधित्व करना है;__str__
मुद्रण के लिए एक अच्छी स्ट्रिंग वापस जाने के लिए है।इसलिए, मैं उन्हें समझना पसंद करता हूं
उपयोगकर्ता के दृष्टिकोण से हालांकि यह एक गलतफहमी है कि मैंने अजगर को सीखते समय बनाया था।
एक छोटा लेकिन अच्छा उदाहरण भी इस प्रकार दिया गया है:
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'
repr
पुन: पेश करने के लिए संदर्भित करने के लिए भ्रामक है । इसे प्रतिनिधित्व के रूप में सोचना बेहतर है।
दिए गए सभी उत्तरों के अलावा, मैं कुछ बिंदुओं को जोड़ना चाहूंगा: -
1) __repr__()
का उपयोग तब किया जाता है जब आप केवल इंटरेक्टिव पाइथन कंसोल पर ऑब्जेक्ट का नाम लिखते हैं और एंटर दबाते हैं।
2) __str__()
जब आप प्रिंट स्टेटमेंट के साथ ऑब्जेक्ट का उपयोग करते हैं, तो उसे लागू किया जाता है।
3) यदि __str__
कोई str()
चीज गायब है, तो __repr__()
ऑब्जेक्ट के इनवोक का उपयोग करके प्रिंट करें और कोई भी फ़ंक्शन ।
4) __str__()
कंटेनरों का, जब आह्वान __repr__()
इसके निहित तत्वों की विधि को निष्पादित करेगा ।
5) के str()
भीतर बुलाया __str__()
बेस मामले के बिना संभावित रूप से पुनरावृत्ति कर सकता है, और अधिकतम पुनरावृत्ति गहराई पर त्रुटि हो सकती है।
6) __repr__()
कॉल कर सकते हैं repr()
जो पहले से प्रतिनिधित्व वाली वस्तु की जगह, स्वचालित रूप से अनंत पुनरावृत्ति से बचने का प्रयास करेगा ...
।
सभी ईमानदारी में, eval(repr(obj))
कभी भी उपयोग नहीं किया जाता है। यदि आप इसका उपयोग करते हुए खुद को पाते हैं, तो आपको रोकना चाहिए, क्योंकि eval
खतरनाक है, और तार अपनी वस्तुओं को क्रमबद्ध करने के लिए एक बहुत ही अक्षम तरीका है ( pickle
इसके बजाय उपयोग करें )।
इसलिए, मैं सेटिंग की सिफारिश करूंगा __repr__ = __str__
। कारण यह है कि तत्वों पर str(list)
कॉल repr
(मैं इसे पायथन के सबसे बड़े डिजाइन दोषों में से एक मानता हूं जिसे पायथन 3 द्वारा संबोधित नहीं किया गया था)। एक वास्तविक repr
शायद के उत्पादन के रूप में बहुत उपयोगी नहीं होगा print [your, objects]
।
इसे योग्य बनाने के लिए, मेरे अनुभव में, repr
फ़ंक्शन का सबसे उपयोगी उपयोग एक स्ट्रिंग को दूसरे स्ट्रिंग के अंदर रखना है (स्ट्रिंग स्वरूपण का उपयोग करके)। इस तरह, आपको उद्धरण या कुछ भी बचने के बारे में चिंता करने की ज़रूरत नहीं है। लेकिन ध्यान दें कि यहां कुछ भी नहीं eval
हो रहा है।
eval(repr(obj))
एक पवित्रता परीक्षण और अंगूठे का एक नियम है - यदि यह मूल वस्तु को सही ढंग से फिर से बनाता है तो आपके पास एक अच्छा __repr__
कार्यान्वयन है। यह इरादा नहीं है कि आप वास्तव में इस तरह से वस्तुओं को क्रमबद्ध करते हैं।
eval
स्वाभाविक रूप से खतरनाक नहीं है। से भी ज्यादा खतरनाक नहीं है unlink
, open
या वे फ़ाइलें लेखन। क्या हमें फाइलों को लिखना बंद कर देना चाहिए क्योंकि शायद कोई दुर्भावनापूर्ण हमला सामग्री को अंदर डालने के लिए एक मनमाना फ़ाइल पथ का उपयोग कर सकता है? सब कुछ खतरनाक है अगर गूंगा लोगों द्वारा विनम्रता से उपयोग किया जाता है। मुहावरा खतरनाक है। धूर्त-क्रुगर प्रभाव खतरनाक हैं। eval
सिर्फ एक फंक्शन है।
अगर सरल शब्द में कहा जाए तो:
__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)
से एक (एक अनौपचारिक) अजगर संदर्भ विकी (संग्रह कॉपी) effbot द्वारा:
__str__
" किसी वस्तु के" अनौपचारिक "स्ट्रिंग प्रतिनिधित्व की गणना करता है। यह इस बात से अलग __repr__
है कि इसमें एक वैध पायथन अभिव्यक्ति होना जरूरी नहीं है: इसके बजाय अधिक सुविधाजनक या संक्षिप्त प्रतिनिधित्व का उपयोग किया जा सकता है। "
__repr__
एक vaild पायथन अभिव्यक्ति को वापस करने के लिए किसी भी तरह की आवश्यकता नहीं है।
str
- दिए गए ऑब्जेक्ट से एक नया स्ट्रिंग ऑब्जेक्ट बनाता है।
repr
- वस्तु का कैनोनिकल स्ट्रिंग प्रतिनिधित्व लौटाता है।
अंतर:
str ():
रेपर ():
एक पहलू जो अन्य उत्तरों में गायब है। यह सच है कि सामान्य तौर पर पैटर्न है:
__str__
: मानव-पठनीय__repr__
: असंदिग्ध, संभवतः मशीन के माध्यम से पठनीयeval
दुर्भाग्य से, यह भेदभाव त्रुटिपूर्ण है, क्योंकि __repr__
एक REPL कंसोल में पायथन आरईपीएल और आईपीथॉन वस्तुओं को प्रिंट करने के लिए भी उपयोग करता है ( पायथन और आईपीथॉन के लिए संबंधित प्रश्न देखें )। इस प्रकार, परियोजनाओं को इंटरेक्टिव कंसोल काम के लिए लक्षित किया जाता है (उदाहरण के लिए, नम्पी या पंडों) ने नियमों को अनदेखा करना शुरू कर दिया है और __repr__
इसके बजाय मानव-पठनीय कार्यान्वयन प्रदान करते हैं ।
पुस्तक धाराप्रवाह पायथन से :
पायथन ऑब्जेक्ट के लिए एक बुनियादी आवश्यकता स्वयं के उपयोग करने योग्य स्ट्रिंग अभ्यावेदन प्रदान करना है, एक डीबगिंग और लॉगिंग के लिए उपयोग किया जाता है, दूसरा उपयोगकर्ताओं को प्रस्तुति के लिए प्रस्तुति के लिए। यही कारण है कि डेटा मॉडल में
विशेष तरीके__repr__
और__str__
मौजूद हैं।
बहुत बढ़िया जवाब पहले से ही बीच के अंतर को कवर __str__
और __repr__
डेवलपर्स के लिए यथासंभव उपयोगी है, जो मेरे लिए पठनीय भी एक अंत उपयोगकर्ता द्वारा पूर्व से किया जा रहा करने पर निर्भर करता है, और बाद किया जा रहा है। यह देखते हुए, मुझे पता है कि __repr__
अक्सर डिफ़ॉल्ट लक्ष्य इस लक्ष्य को प्राप्त करने में विफल रहता है क्योंकि यह डेवलपर्स के लिए उपयोगी जानकारी को छोड़ देता है।
इस कारण से, यदि मेरे पास एक सरल पर्याप्त है __str__
, तो मैं आमतौर पर दोनों दुनिया के सर्वश्रेष्ठ को कुछ इस तरह से प्राप्त करने की कोशिश करता हूं:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
ध्यान रखने वाली एक महत्वपूर्ण बात यह है कि कंटेनर में
__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__
) परिभाषित नहीं होता है! तो, आप गलत हैं।
संक्षेप में:
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'
>>> 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__()
। सभी पायथन ऑब्जेक्ट्स के दो आउटपुट फॉर्म हैं। स्ट्रिंग फॉर्म को मानव-पठनीय बनाया गया है। प्रतिनिधित्वात्मक रूप से उत्पादन के लिए डिज़ाइन किया गया है कि अगर पायथन इंटरप्रेटर को खिलाया जाता है (जब संभव हो) प्रतिनिधित्व की गई वस्तु को पुन: उत्पन्न करता है।
__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
समझ __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
आशा है कि आप अधिक उत्तर तलाशने के लिए ठोस आधार बनाने में मदद करेंगे।
__str__
स्ट्रिंग ऑब्जेक्ट को वापस करना चाहिए, जबकि __repr__
किसी भी अजगर अभिव्यक्ति को वापस कर सकते हैं।__str__
कार्यान्वयन गायब है, तो __repr__
फ़ंक्शन का उपयोग फ़ॉलबैक के रूप में किया जाता है। यदि __repr__
फ़ंक्शन कार्यान्वयन गायब है, तो इसमें कोई कमी नहीं है।__repr__
फ़ंक्शन ऑब्जेक्ट का स्ट्रिंग प्रतिनिधित्व वापस कर रहा है, तो हम __str__
फ़ंक्शन के कार्यान्वयन को छोड़ सकते हैं ।स्रोत: https://www.journaldev.com/22460/python-str-repr-functions