2009-12-20 4 views
9

파이썬 2.5에서는 float 숫자를 수정 된 __str__() 메소드와 함께 사용해야합니다. 또한 생성자가 실패 할 때도 알 필요가 있습니다.파이썬에서 서브 클래스 float 타입은 __init에서 예외를 포착하지 못합니다 __()

float.__init__()에서 발생하는 예외를 잡을 수없는 이유는 무엇입니까?

파생 된 float 객체의 숫자 값을 참조하는 가장 좋은 방법은 무엇입니까? 내 코드에서 나는 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__에서 발생합니다.

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__을 제거 할 수 있습니다

그래서, 당신의 float 서브 클래스는 시작해야합니다. 이제 :

>>> 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"에 대해서, 문자열 변환에 어떤 메소드가 사용됩니까? 'float .__ str __()'? 무한 재귀가 없기 때문에 그것이 아닌'F .__ str __()'이라고 생각했습니다. – Ricardo

관련 문제