पायथन __str__ और सूचियाँ


107

जावा में, अगर मैं List.toString () को कॉल करता हूं, तो यह स्वचालित रूप से सूची के अंदर प्रत्येक ऑब्जेक्ट पर toString () विधि को कॉल करेगा। उदाहरण के लिए, यदि मेरी सूची में ऑब्जेक्ट्स O1, o2 और o3 हैं, तो list.toString () कुछ इस तरह दिखाई देगा:

"[" + o1.toString() + ", " + o2.toString() + ", " + o3.toString() + "]"

क्या पायथन में समान व्यवहार प्राप्त करने का एक तरीका है? मैंने अपनी कक्षा में एक __str __ () विधि लागू की, लेकिन जब मैं वस्तुओं की एक सूची का उपयोग करके प्रिंट करता हूं:

print 'my list is %s'%(list)

यह कुछ इस तरह दिखता है:

[<__main__.cell instance at 0x2a955e95f0>, <__main__.cell instance at 0x2a955e9638>, <__main__.cell instance at 0x2a955e9680>]

मैं अपने __str__ को स्वचालित रूप से सूची के अंदर प्रत्येक तत्व के लिए (या उस मामले के लिए तानाशाह) कैसे कह सकता हूं?


संदर्भ के लिए, PEP 3140 है: "str (कंटेनर) को str (आइटम), न कि repr (आइटम)" कहा जाना चाहिए , जिसे अस्वीकार कर दिया गया।
एलेक्सी

जवाबों:


133

अजगर सूची में स्ट्रिंग को कॉल करना __repr__प्रत्येक तत्व के अंदर विधि को कॉल करता है। कुछ वस्तुओं के लिए, __str__और __repr__समान हैं। यदि आप चाहते हैं कि व्यवहार,

def __str__(self):
    ...
def __repr__(self):
    return self.__str__()

7
पहचान __str__के साथ __repr__आमतौर पर से सहमत नहीं है पायथन डेटा मॉडल है, तो सूची समझ समाधान @ डैनियल-ल्यू द्वारा प्रस्तावित अधिक pythonic है।
Ioannis Filippidis

2
कोई तर्क नहीं। मैंने पूछे गए सवाल का जवाब दिया, जो अक्सर यह होता है कि एक नवागंतुक अजगर समस्या के बारे में कैसे सोचना चाहता है, लेकिन इसका मतलब यह नहीं है कि जवाब देने का सबसे अच्छा तरीका है।
डेविड बर्जर

1
पायथन को अपने स्वयं के डेटा मॉडल के अनुरूप होना चाहिए और सभी प्राइमेटिव और एग्रीगेट्स के लिए एक ही काम करना चाहिए।
टेरेंस ब्रान्नॉन

2
मुझे लगता है कि अजगर सूची के लिए डिफ़ॉल्ट व्यवहार सादा गलत है। मुझे उम्मीद है कि str()सूची में str()प्रत्येक व्यक्तिगत तत्वों के लिए अंदर लौट आए ।
सुपरगो

21

आप प्रत्येक आइटम str () के स्वचालित रूप से नई सूची बनाने के लिए एक सूची समझ का उपयोग कर सकते हैं :

print([str(item) for item in mylist])

6
या बस print(map(str, mylist))- यह एक छोटा सा कम है
anula

4
इसके साथ एक समस्या यह है कि यदि सूची में आइटम भी एक सूची हो सकती है
Breandán Dalton

7

दो आसान चीजें जो आप कर सकते हैं, mapफ़ंक्शन का उपयोग करें या एक समझ का उपयोग करें।

लेकिन यह आपको स्ट्रिंग की सूची नहीं, बल्कि एक स्ट्रिंग के रूप में मिलती है। तो आपको भी साथ में तार जुड़ना होगा।

s= ",".join( map( str, myList ) )

या

s= ",".join( [ str(element) for element in myList ] )

तब आप इस संयुक्त स्ट्रिंग ऑब्जेक्ट को प्रिंट कर सकते हैं।

print 'my list is %s'%( s )

4

क्या आप उस आउटपुट का उपयोग करना चाहते हैं, इसके आधार पर, शायद __repr__अधिक उपयुक्त हो सकता है:

import unittest

class A(object):
    def __init__(self, val):
        self.val = val

    def __repr__(self):
        return repr(self.val)

class Test(unittest.TestCase):
    def testMain(self):
        l = [A('a'), A('b')]
        self.assertEqual(repr(l), "['a', 'b']")

if __name__ == '__main__':
    unittest.main()

3

मैं ऐसा करने के लिए सूची समझ का उपयोग करने के बारे में पिछले उत्तर से सहमत हूं, लेकिन आप निश्चित रूप से एक फ़ंक्शन के पीछे छिपा सकते हैं, अगर वह आपकी नाव पर तैरता है।

def is_list(value):
    if type(value) in (list, tuple): return True
    return False

def list_str(value):
    if not is_list(value): return str(value)
    return [list_str(v) for v in value]

बस मज़े के लिए, मैंने सूची में शामिल सब कुछ (सूची) को पुनरावर्ती रूप से str () बनाया।


+1 लागू होने पर __str__और __repr__अलग से यह उपयोगी है
विन्सेन्ट ग्रेविटस


0

यह पर्याप्त होना चाहिए।

जब मुद्रण सूचियों के साथ-साथ अन्य कंटेनर कक्षाएं होती हैं, तो निहित तत्वों का उपयोग करके मुद्रित किया जाएगा __repr__, क्योंकि __repr__इसका उपयोग आंतरिक वस्तु प्रतिनिधित्व के लिए किया जाना है। अगर हम कहते हैं: help(object.__repr__)यह हमें बताएगा:

Help on wrapper_descriptor:

__repr__(self, /)
    Return repr(self).

और अगर हम कहते हैं 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.

यदि __str__किसी वस्तु के लिए लागू किया गया है और डिफ़ॉल्ट आउटपुट का उत्पादन __repr__नहीं repr(obj)करेगा, ठीक उसी तरह print(obj)जब इनमें से कोई भी लागू किया जाता है।

तो एकमात्र तरीका है __repr__अपनी कक्षा के लिए लागू करना। ऐसा करने का एक संभावित तरीका यह है:

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

C.__repr__=C.__str__       
ci = C()    


print(ci)       #C class str 
print(str(ci))  #C class str 
print(repr(ci)) #C class str 

-3

आपको जो आउटपुट मिल रहा है, वह ऑब्जेक्ट का मॉड्यूल नाम, क्लास नाम और फिर हेक्साडेसिमल में मेमोरी एड्रेस है __repr__ फ़ंक्शन को ओवरराइड नहीं किया गया है।

__str__प्रिंट का उपयोग करते समय किसी ऑब्जेक्ट के स्ट्रिंग प्रतिनिधित्व के लिए उपयोग किया जाता है। लेकिन जब से आप वस्तुओं की एक सूची मुद्रित कर रहे हैं, और strप्रत्येक आइटम के लिए विधि को कॉल करने के लिए सूची पर पुनरावृत्ति नहीं कर रहा है, यह वस्तुओं के प्रतिनिधित्व को प्रिंट करता है।

करवाने के लिए __str__समारोह लागू आप इस तरह कुछ करने के लिए आवश्यकता होगी:

'my list is %s' % [str(x) for x in myList]

यदि आप __repr__फ़ंक्शन को ओवरराइड करते हैं तो आप प्रिंट विधि का उपयोग कर सकते हैं जैसे आप पहले थे:

class cell:
    def __init__(self, id):
        self.id = id
    def __str__(self):
        return str(self.id) # Or whatever
    def __repr__(self):
        return str(self) # function invoked when you try and print the whole list.

myList = [cell(1), cell(2), cell(3)]
'my list is %s' % myList

फिर आपको my list is [1, 2, 3]अपने आउटपुट के रूप में " " मिलेगा ।


यह उत्तर पूरी तरह से असंबंधित प्रश्न का उत्तर देता प्रतीत होता है। क्या आप वाकई इसे सही जगह पर रखना चाहते हैं?
ब्लेकनाथ

हाँ ब्लेकनाथ ने इस पृष्ठ को जो मैं अपना उत्तर देना चाहता था, एक अन्य पोस्ट से इस पृष्ठ का लिंक दिया था। क्योंकि इसने मुझे यहाँ निर्देशित किया और मैं यहाँ उत्तर देता हूँ कि जिस व्यक्ति ने प्रश्न किया है वह यहाँ फिर से आएगा और मेरे उत्तर को देखेगा। अनिश्चितता !!!
पैनागविटिस कोलीगास

यदि दूसरे प्रश्न को इस के डुप्लिकेट के रूप में बंद कर दिया गया था, तो यह मान लिया गया है कि यहां मौजूद उत्तर पहले से ही दूसरे प्रश्न का ध्यान रखना चाहिए। यदि ऐसा नहीं है, तो आपको उस प्रश्न को फिर से खोलने के लिए फ़्लैगिंग करना चाहिए, बजाय यहाँ एक असंगत उत्तर पोस्ट करने के, जो लगभग निश्चित रूप से हटा दिया जाएगा। अब, यह संभव है कि आपके पास कहने के लिए कुछ है जो यहां 8 अन्य उत्तरों में से एक द्वारा कवर नहीं किया गया है, लेकिन आपको इस पृष्ठ के संदर्भ में अपना जवाब देने की आवश्यकता होगी, क्योंकि यह सवाल है जिसका आप जवाब दे रहे हैं। और दो समान उत्तर पोस्ट न करें!
ब्लैंकनाथ

1
ओह, हालांकि अब जब मैं इसे फिर से देखता हूं, तो ऐसा लगता है कि @charliebeckwith ने आपके पोस्ट को पूरी तरह से अलग करने के लिए संपादित किया है, बजाय उनके खुद के जवाब पोस्ट करने के, कुछ अकथनीय कारण के लिए। यह सामान्य रूप से नहीं है कि संपादन कैसे काम करता है ...
ब्लैंकनाथ

@blckknght मैंने इसे संपादित करना शुरू किया, इससे पहले कि मुझे एहसास हो जाता कि उत्तर कैसे बंद था। पूरी तरह से अक्षम्य क्यों मैं जा रहा रखा है।
चार्लीबेकविथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.