2009-12-20 13 views
9

पर अपवाद पकड़ने में विफल रहता है Python 2.5 पर मुझे एक संशोधित __str__() विधि के साथ फ्लोट नंबरों का उपयोग करने की आवश्यकता है। इसके अलावा मुझे यह जानने की जरूरत है कि जब निर्माता विफल रहता है।पायथन में उप-वर्गीकरण फ्लोट प्रकार, __init __()

मैं float.__init__() से उठाए गए अपवादों को क्यों नहीं पकड़ सकता?

मेरी व्युत्पन्न फ्लोट ऑब्जेक्ट के संख्यात्मक मूल्य से परामर्श करने का सबसे अच्छा तरीका क्या है? मेरे कोड में मैं float(self) का उपयोग कर रहा हूं।

class My_Number(float): 
    def __init__(self, float_string): 
     try: 
      super(My_Number, self).__init__(float_string) 
     except (TypeError, ValueError): 
      raise My_Error(float_string) 

    def __str__(self): 
     if int(float(self)) == float(self): 
      return str(int(float(self))) 
     else: 
      return str(round(float(self), 2)) 


>>> n = My_Number('0.54353') 
>>> print n 
0.54 

>>> n = My_Number('5.0') 
>>> print n 
5 

>>> n = My_Number('foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for float(): foo 

उत्तर

17

:

class F(float): 
    def __new__(cls, *arg, **kw): 
     try: 
      return float.__new__(cls, *arg, **kw) 
     except ValueError: 
      raise Exception("foo") 

print F("3.5")    
print F("asdf") 

इसके अलावा "स्व" एक नाव पहले से ही ऐसा नहीं कहने के लिए नाव (स्वयं) की जरूरत है, बस "स्व" क्या करेंगे है float अपरिवर्तनीय है, इसलिए __init__, प्रारंभकर्ता, मूल रूप से एक नो-ऑप है - वहां कुछ भी नहीं हो सकता है, हो सकता है कारण self ऑब्जेक्ट को बदला नहीं जा सकता है (यदि यह वास्तव में उप-वर्ग की बजाय float का उदाहरण है - लेकिन निश्चित रूप से float का स्वयं का __init__ उस धारणा पर कार्य करना चाहिए ;-)।

इसलिए, सभी कार्रवाई __new__ में होता है, निर्माता उचित, बस अन्य अपरिवर्तनीय प्रकार के लिए की तरह int, str, tuple, और इतने पर की तरह। यह मानना ​​एक आम गलती है कि __init__ एक कन्स्ट्रक्टर है: ऐसा नहीं है, यह पहले से ही निर्मित ऑब्जेक्ट को अपना पहला तर्क, self के रूप में लेता है, और इसे "प्रारंभ" करता है (यदि व्यवहार्य है, यानी, यदि self उत्परिवर्तनीय है! -) - निर्माण स्वयं __new__ में होता है।

तो, अपने float उपवर्ग शुरू कर देना चाहिए:

class My_Number(float): 
    def __new__(cls, float_string): 
    try: return float.__new__(cls, float_string) 
    except (TypeError, ValueError): raise My_Error(float_string) 

और आप __init__ है, जो की जरूरत नहीं है निकाल सकते हैं। अब:

>>> n = My_Number('foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in __new__ 
NameError: global name 'My_Error' is not defined 

(जाहिर है, इसे और भी बेहतर काम करेगा अगर आप किया एक My_Error अपवाद वर्ग परिभाषित किया गया है ;-)।

+0

काम करता है !, स्पष्टीकरण के लिए धन्यवाद। – Ricardo

7

बजाय __new__ कोशिश:

def __str__(self): 
    return "%.2f" % self 
+0

धन्यवाद !, पूरी तरह से काम किया। '% .2f"% self' के बारे में, स्ट्रिंग रूपांतरण के लिए किस विधि का उपयोग किया जाता है? 'नाव .__ str __()'? मैंने सोचा कि यह 'एफ .__ str __() 'था जो यह नहीं है, क्योंकि अनंत रिकर्सन नहीं है। – Ricardo

संबंधित मुद्दे