इस वर्ग पर विचार करें:
class foo(object):
pass
डिफ़ॉल्ट स्ट्रिंग प्रतिनिधित्व कुछ इस तरह दिखता है:
>>> str(foo)
"<class '__main__.foo'>"
मैं इस प्रदर्शन को कस्टम स्ट्रिंग कैसे बना सकता हूं?
इस वर्ग पर विचार करें:
class foo(object):
pass
डिफ़ॉल्ट स्ट्रिंग प्रतिनिधित्व कुछ इस तरह दिखता है:
>>> str(foo)
"<class '__main__.foo'>"
मैं इस प्रदर्शन को कस्टम स्ट्रिंग कैसे बना सकता हूं?
जवाबों:
लागू करें __str__()
या __repr__()
कक्षा के मेटाक्लस में।
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object):
__metaclass__ = MC
print C
का प्रयोग करें __str__
आप एक पठनीय stringification, उपयोग मतलब अगर __repr__
स्पष्ट अभ्यावेदन के लिए।
_representation
क्लास बॉडी और मेटाक्लस return self._representation
की __repr__()
विधि में एक स्ट्रिंग जोड़ सकते हैं ।
__repr__
का प्रतिनिधित्व नहीं करना चाहते हैं C
। एक _representation
सदस्य होने का एक विकल्प एक मेटाक्लास फैक्ट्री बनाना है जो उचित के साथ एक मेटाक्लास का उत्पादन करता है __repr__
(यह अच्छा हो सकता है यदि आप इसे बहुत उपयोग कर रहे हैं)।
class foo(object):
def __str__(self):
return "representation"
def __unicode__(self):
return u"representation"
instances
वर्ग के लिए स्ट्रिंग प्रतिनिधित्व को बदलता है, केवल कक्षा के लिए नहीं।
यदि आपको पहले एक के बीच चयन करना है __repr__
या __str__
जाना है, जैसा कि डिफ़ॉल्ट कार्यान्वयन __str__
कॉल द्वारा __repr__
परिभाषित नहीं किया गया था।
कस्टम वेक्टर 3 उदाहरण:
class Vector3(object):
def __init__(self, args):
self.x = args[0]
self.y = args[1]
self.z = args[2]
def __repr__(self):
return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)
def __str__(self):
return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)
इस उदाहरण में, repr
फिर से एक स्ट्रिंग देता है जिसे सीधे उपभोग / निष्पादित किया जा सकता है, जबकि str
डिबग आउटपुट के रूप में अधिक उपयोगी है।
v = Vector3([1,2,3])
print repr(v) #Vector3([1,2,3])
print str(v) #x:1, y:2, z:3
__repr__
बनाम के बारे में आपकी बात __str__
सही है, यह वास्तविक प्रश्न का उत्तर नहीं देता है, जो वर्ग-वस्तुओं के बारे में है, उदाहरणों के बारे में नहीं।
इग्नासियो वाज़क्वेज़-अब्राम्स का स्वीकृत उत्तर काफी सही है। हालांकि, यह पायथन 2 पीढ़ी से है। अब के मौजूदा पायथन 3 के लिए एक अपडेट होगा:
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
यदि आप ऐसा कोड चाहते हैं जो Python 2 और Python 3 दोनों पर चलता है, तो आपके द्वारा कवर किया गया छह मॉड्यूल:
from __future__ import print_function
from six import with_metaclass
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(with_metaclass(MC)):
pass
print(C)
अंत में, यदि आपके पास एक वर्ग है जिसे आप एक कस्टम स्टेटिक रीप चाहते हैं, तो ऊपर स्थित क्लास-आधारित दृष्टिकोण शानदार काम करता है। लेकिन अगर आपके पास कई हैं, तो आपको MC
प्रत्येक के लिए इसी तरह का एक मेटाक्लस जेनरेट करना होगा , और वह थकाऊ हो सकता है। उस स्थिति में, अपने मेटाप्रोग्रामिंग को एक कदम आगे ले जाना और मेटाक्लास फैक्टरी बनाने से चीजें थोड़ी साफ हो जाती हैं:
from __future__ import print_function
from six import with_metaclass
def custom_class_repr(name):
"""
Factory that returns custom metaclass with a class ``__repr__`` that
returns ``name``.
"""
return type('whatever', (type,), {'__repr__': lambda self: name})
class C(with_metaclass(custom_class_repr('Wahaha!'))): pass
class D(with_metaclass(custom_class_repr('Booyah!'))): pass
class E(with_metaclass(custom_class_repr('Gotcha!'))): pass
print(C, D, E)
प्रिंट:
Wahaha! Booyah! Gotcha!
Metaprogramming ऐसी चीज़ नहीं है जिसकी आपको आम तौर पर हर रोज़ ज़रूरत पड़ती है- लेकिन जब आपको इसकी ज़रूरत होती है, तो यह वास्तव में मौके पर पहुँच जाती है!
बस सभी ठीक उत्तरों को जोड़ते हुए, सजावट के साथ मेरा संस्करण:
from __future__ import print_function
import six
def classrep(rep):
def decorate(cls):
class RepMetaclass(type):
def __repr__(self):
return rep
class Decorated(six.with_metaclass(RepMetaclass, cls)):
pass
return Decorated
return decorate
@classrep("Wahaha!")
class C(object):
pass
print(C)
stdout:
Wahaha!
नीचे की ओर:
C
सुपर क्लास के बिना घोषित नहीं कर सकते (नहीं class C:
)C
उदाहरण कुछ अजीब व्युत्पत्ति के उदाहरण होंगे, इसलिए यह __repr__
उदाहरणों के लिए भी जोड़ना एक अच्छा विचार है ।