Python의 마법 방법 III

2024. 4. 9. 19:09python/advanced

산술 연산자에 대한 추가 정보

연산자를 지원하는 매직 메소드는 expression을 포함하고 있는 각 객체의 상대적 위치에 영향을 받습니다. 그렇기 때문에 위 섹션에서 displacement는 킬로미터 단위이고 total은 미터 단위입니다.

.__add__()을 예를 들어 보겠습니다. Python은 왼쪽 피연산자에서 이 메서드를 호출합니다. 해당 피연산자가 메서드를 구현하지 않으면 작업이 실패합니다. 왼쪽 피연산자가 메서드를 구현하지만 해당 구현이 원하는 대로 작동하지 않는 경우 문제가 발생할 수 있습니다. 다행히도 Python에는 이러한 문제를 해결할 수 있는 올바른 버전의 .__r*__()라는 연산자 메서드( )가 있습니다. 예를 들어, 객체와 정수 또는 부동 소수점 숫자 사이의 덧셈을 지원하는 Number 클래스를 작성한다고 가정해 보겠습니다. 그러한 상황에서는 다음과 같은 작업을 수행할 수 있습니다.

(참고) 아래 코드를 number.py으로 저장하십시요

In [ ]:
class Number:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        print("__add__ called")
        if isinstance(other, Number):
            return Number(self.value + other.value)
        elif isinstance(other, int | float):
            return Number(self.value + other)
        else:
            raise TypeError("unsupported operand type for +")

    def __radd__(self, other):
        print("__radd__ called")
        return self.__add__(other)

.__add__() 메서드는 덧셈 표현식에서 왼쪽 연산자로 Number 인스턴스를 사용할 때 작동합니다. 반면에 .__radd__()는 오른쪽 피연산자로 Number 인스턴스를 사용할 때 작동합니다. 메소드 이름의 시작 부분에 있는 r은 right를 나타냅니다.

Number class 진행 방식은 다음과 같습니다.

In [ ]:
from number import Number

five = Number(5)
ten = Number(10)

fifteen = five + ten
In [ ]:
fifteen.value
In [ ]:
six = five + 1
In [ ]:
six.value
In [ ]:
twelve = 2 + ten
In [ ]:
twelve.value

이 코드 조각에서는 Number의 두 인스턴스를 만듭니다. 그런 다음 Python이 예상대로 .__add__()을 호출하는 추가에서 이를 사용합니다. 다음으로 클래스와 int 유형을 혼합하는 표현식에서 왼쪽 연산자로 five을 사용합니다. 이 경우 Python이 다시 Number.__add__()을 호출합니다.

마지막으로 덧셈의 오른쪽 피연산자로 ten을 사용합니다. 이번에는 Python이 암시적으로 Number.__radd__()를 호출하고 Number.__add__() 호출로 대체됩니다.

.r*() 메서드를 요약하면 다음과 같습니다.

운영자                오른손 방법
+ .__radd__(self, other)
- .__rsub__(self, other)
* .__rmul__(self, other)
/ .__rtruediv__(self, other)
// .__rfloordiv__(self, other)
% .__rmod__(self, other)
** .__rpow__(self, other[, modulo])

Python은 왼쪽 피연산자가 해당 연산을 지원하지 않고 피연산자의 유형이 다른 경우 이러한 메서드를 호출합니다.

Python에는 단항 연산자도 있습니다. 단일 피연산자에서 동작하기 때문에 단항이라고 부릅니다.

 
운영자  지원방법                                       설명
- .__neg__(self) 반대 부호를 사용하여 목표 값을 반환합니다.
+ .__pos__(self) 변환을 수행하지 않고 부정에 대한 보완을 제공합니다.

Python의 내장 숫자 유형에서 이러한 연산자를 오버로드하고 자체 클래스에서 지원할 수도 있습니다.

비교 연산자 방법

또한 비교 연산자 뒤에는 특별한 방법이 있다는 것도 알게 될 것입니다. 예를 들어, 5 < 2와 같은 것을 실행하면 Python은 .lt() 매직 메서드를 호출합니다. 다음은 모든 비교 연산자와 지원 방법에 대한 요약입니다.

운영자지원방법
< .__lt__(self, other)
<= .__le__(self, other)
== .__eq__(self, other)
!= .__ne__(self, other)
>= .__ge__(self, other)
> .__gt__(self, other)

사용자 정의 클래스에서 이러한 메서드 중 일부를 사용하는 방법을 예시로 들기 위해 여러 개의 서로 다른 사각형을 만드는 Rectangle 클래스를 작성한다고 가정해 보겠습니다. 당신은 이 직사각형들을 비교할 수 있기를 원합니다.

다음은 같음( ==), 보다 작음( <) 및 보다 큼( >) 연산자를 지원하는 Rectangle 클래스 입니다.

(참고) 다음 코드를 rectangle.py으로 저장 하십시요.

In [ ]:
class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def area(self):
        return self.height * self.width

    def __eq__(self, other):
        return self.area() == other.area()

    def __lt__(self, other):
        return self.area() < other.area()

    def __gt__(self, other):
        return self.area() > other.area()

클래스에는 높이와 너비를 사용하여 직사각형의 면적을 계산하는 .__area__() 메서드가 있습니다. 그러면 의도한 비교 연산자를 지원하는 데 필요한 세 가지 특수 메서드가 있습니다. 이들 모두는 최종 결과를 결정하기 위해 직사각형의 면적을 사용한다는 점에 유의하십시오.

class가 실제로 진행되는 방식은 다음과 같습니다.

from rectangle import Rectangle

basketball_court = Rectangle(15, 28)
soccer_field = Rectangle(75, 110)

basketball_court < soccer_field
In [ ]:
basketball_court > soccer_field
In [ ]:
basketball_court == soccer_field
In [ ]:
basketball_court == soccer_field

 

<출처 : https://realpython.com/python-magic-methods/>

'python > advanced' 카테고리의 다른 글

Python의 마법 방법 VI  (0) 2024.04.12
Python의 마법 방법 V  (0) 2024.04.11
Python의 마법 방법 IV  (0) 2024.04.11
Python의 마법 방법 II  (0) 2024.04.08
Python의 마법 방법 I  (0) 2024.04.07