2010-03-02 3 views
4

동일한 클래스의 객체를 함께 더하기/곱하기/나누기 또는 숫자 인자를 각 클래스 멤버에 추가/곱할 수있는 클래스를 만들려고합니다.python을 사용하여 다형 산술 연산자를 구현하는 방법은 무엇입니까?

그래서 수업은 좌표계입니다. 밖에 나가서 할 수있는 것보다 내가 원하는 모든 것을하는 훌륭한 패키지가 있음을 알고 있습니다. 그러나 지금은 단지 호기심입니다.)

class GpsPoint(object): 
    """A class for representing gps coordinates""" 
    def __init__(self, x, y, z): 
     self.x = x 
     self.y = y 
     self.z = z 
    def __add__(self, other): 
     return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z) 
    def __radd__(self, other): 
     return GpsPoint(self.x + other, self.y + other, self.z + other) 
    def __str__(self): 
     return "%d, %d, %d" % (self.x, self.y, self.z) 

이것은 원래 시도한 것입니다. 나는 일을 찾았지만, 나는

>>foo = GpsPoint(1,2,3) 
>>print 5 + foo 
6, 7, 8 
>>print foo + 5 
AttributeError: 'int' object has no attribute 'x' 

그래서,이 작업을 수행 할 수있는 파이썬 방법은 무엇인가하는 파이썬 방법은,이이 그냥 바보 첫번째 숫자 인수를 사용하는 경우에만? 나는 철학적 인 문제가 isinstance()을 사용하는 것을 본다. 그리고 나는 tryexcept 블록을 던질 수 있었다라는 것을 알고있다. 나는 단지 호기심을 느낀다. 나는 이어야한다.는 이것에 관해 가야한다.

답변

6

"Pythonic"방법은 "허가보다 용서를 구하는 것"입니다. 즉, 사전에 유형을 확인하는 대신에 추가를 시도하고, 실패하면 예외를 잡아서 처리합니다.

class GpsPoint(object): 
    """A class for representing gps coordinates""" 
    def __init__(self, x, y, z): 
     self.x = x 
     self.y = y 
     self.z = z 
    def __add__(self, other): 
     try: 
      return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z) 
     except AttributeError: 
      return GpsPoint(self.x + other, self.y + other, self.z + other) 
    def __radd__(self, other): 
     try: 
      return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z) 
     except AttributeError: 
      return GpsPoint(self.x + other, self.y + other, self.z + other) 
    def __str__(self): 
     return "%d, %d, %d" % (self.x, self.y, self.z) 
+0

거짓 동조 문제를 해결하는 좋은 방법은 용서를 요구하는 것이지만 과부하 숫자 연산자의 경우 x, y 및 z가 의미하는 바가 명확합니다. 말하자면 완전히 관련이없는 4 차원 (w, x, y, z) 숫자 클래스의 인스턴스를 추가하는 경우에만 문제가 발생합니다. 그러면 자동으로 w가 손실됩니다. – markpasc

+0

신난다, 고마워. 이것이 내가 끝낸 것입니다 (그리고'__radd__ = __add__'). 나는 약간 hacky 인 것처럼 느낀다. 그러나 그것은 나의 목적에 잘 어울리고, 대답으로 좋아 보인다. – Tyler

+1

예외 블록이 반환 된 경우 'self + GpsPoint (other, other, other) ' 숫자를 GpsPoint로 매핑하고이를 GpsPoint로 변경 한 다음 추가하는 것이 더 좋습니다. –

2

적어도 GpsPoint과 호환되는 범위 내에서 어떤 유형이 other인지 확인해야합니다. 알아낼 수없는 경우 NotImplemented을 반환하면 해석기가 거기에서 처리하려고 시도합니다.

0

짧은 대답 : isinstance()를 사용하십시오.

"기타"유형을 결정하는 다른 방법은 없습니다. 또한, 많은 파이썬 라이브러리의 소스를 확인하면 isinstance()가 사용되는 곳이 많이 있다는 것을 알 수 있습니다. 그래서 이것은 파이썬의 예술 상태에 불과합니다 :-).

관련 문제