English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python 기본 강의

Python 흐름 제어

Python 함수

Python 데이터 타입

Python 파일 처리

Python 객체와 클래스

Python 날짜와 시간

Python 고급 지식

Python 참조 매뉴얼

Python 연산자 오버로드

사용자가 사용하는 연산자에 따라 Python에서 연산자의 의미를 변경할 수 있습니다. 이 방법을 연산자 오버로드라고 합니다.

Python에서 연산자 오버로드는 무엇인가요?

파이썬 연산자내장 클래스에 사용됩니다. 하지만 동일한 연산자가 다른 타입에 대해서는 다른 동작을 합니다. 예를 들어,+연산자는 두 숫자에 대해서는 수학적 더하기 연산을 수행하고, 두 리스트를 결합하고, 두 문자열을 연결합니다.

Python에서 이 기능은 동일한 연산자가 상황에 따라 다른 의미를 가질 수 있도록 합니다. 이를 연산자 오버로드라고 합니다.

그런 다음, 사용자 정의 클래스의 객체와 함께 사용할 때 어떻게 될까요? 아래의 클래스를 보세요. 이 클래스는 두차원 고리에서 포인트를 모델링합니다.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y

그래서, 코드를 실행하고 Python 셸에서 두 개의 포인트를 더하는 것을 시도해 보세요.

>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> p1 + p2
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'

와! 이 많은 오류가 있습니다. 두 개의 Point 객체를 더하는 데 Python이 어떻게 할 수 없게 되었는지 TypeError가 발생합니다.

또한, 좋은 소식은 계산자 오버로드를 통해 Python에 이 점을 가르칠 수 있다는 것입니다. 그러나 먼저, 특수 함수에 대해 이해해야 합니다.

Python의 특수 함수

Python에서 __로 시작하는 클래스 함수는 특수 함수라고 합니다. 이유는 이들은 일반 함수가 아니기 때문입니다. 우리가 정의한 __init__() 함수는 이들 중 하나입니다. 새로운 객체를 생성할 때마다 이 함수가 호출됩니다. Python에는 많은 특수 함수가 있습니다.

특별한 함수를 사용하여, 클래스를 내장 함수와 호환시킬 수 있습니다.

>>> p1 = Point(2,3)
>>> print(p1)
<__main__.Point object at 0x00000000031F8CC0>

출력 결과는 예상보다 나빴습니다. 하지만, 클래스에서 __str__() 메서드를 정의하면, 출력 방식을 제어할 수 있습니다. 이를 클래스에 추가합니다.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)

이제 다시 print() 함수를 시도해 보겠습니다。

>>> p1 = Point(2,3)
>>> print(p1)
(2,3)

 실제로는,内置 함수 str()나 format()를 사용할 때, 같은 메서드를 호출합니다.

>>> str(p1)
을 호출할 때2,3)을 호출할 때
>>> format(p1)
을 호출할 때2,3)을 호출할 때

따라서, 당신이 str(p1)이나 format(p1)을 호출할 때, Python은 내부에서 p1__str__()를 오버로드하면, 특별한 함수로 알려져 있습니다. 그 다음, 연산자 오버로드로 돌아가겠습니다。

Python에서 오버로드+연산자

을 오버로드하려면+기호를 오버로드하려면, 클래스에서 __add__() 함수를 구현해야 합니다. 권리를 가지면 동시에 중대한 책임도 맡게 됩니다. 이 함수 내에서 원하는 일을 할 수 있습니다. 하지만 좌표의 합을 반환하는 Point 객체를 반환하는 것이 현명합니다.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)
    
    def __add__(self,other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x,y)

이제 다시 시도해 보겠습니다。

>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> print(p1 + p2)
(1,5)

실제로는, 당신이 p1 + p2할 때, Python은 p1 __ add __(p2),즉 Point .__ add __(p1,p2)。 마찬가지로, 다른 연산자도 오버로드할 수 있습니다. 필요한 특별한 함수 목록은 다음과 같습니다。

Python에서 연산자 오버로드의 특별한 함수
연산자표현내부
더하기(+)p1 + p2p1 __ add __(p2)
빼기(-)p1-p2p1 __ sub __(p2)
곱하기(*)p1 * p2p1 __ mul __(p2)
승幂(**)p1 ** p2p1 __ pow __(p2)
정확한 나누기(/)p1 / p2p1 __ truediv __(p2)
정수로 나누기(//)
p1 // p2p1 __ floordiv __(p2)
모듈러 연산(%)p1%p2p1 __ mod __(p2)
비트 왼쪽 이동(<<)p1 << p2p1 __ lshift __(p2)
비트 오른쪽 이동(>>)p1 >> p2p1 __ rshift __(p2)
비트 이이스(and)p1 and p2p1 __ and __(p2)
비트 이이스(or)p1 | 2p1 __ or __(p2)
비트 이이스(xor)p1 ^ p2p1 __ xor __(p2)
비트 반전(~)〜p1p1 __ invert __()

파이썬에서 비교 연산자를 오버로드

파이썬은 연산자 오버로드를 수학 연산자로 제한하지 않습니다. 비교 연산자도 오버로드할 수 있습니다.

Point 클래스에서 작은거다(<) 연산자를 구현하고 싶다면, 이렇게 할 수 있습니다. 이는 원점에서 이 점들의 크기를 비교하고 결과를 반환하기 위해 목적을 가지고 있습니다.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)
    
    def __lt__(self,other):
        self_mag = (self.x ** 2) + (self.y ** 2)
        other_mag = (other.x ** 2) + (other.y ** 2)
        return self_mag < other_mag

이 예제들을 파이썬 셸에서 실행해 보세요.

>>> Point(1,1) < Point(-2,-3)
True
>>> Point(1,1) < Point(0.5,-0.2)
False
>>> Point(1,1) < Point(1,1)
False

또한, 다음은 다른 비교 연산자를 오버로드하기 위해 필요한 특별한 함수들을 나열합니다.

파이썬에서의 비교 연산자 오버로드
연산자
표현식내부
작은거다(<)p1 <p2p1 __ lt __(p2)
작은거 같다(<=)p1 <= p2p1 __ le __(p2)

같다(==)

p1 == p2p1 __ eq __(p2)
불 같다(!=)p1!= p2p1 __ ne __(p2)
큰거다(>)p1> p2p1 __ gt __(p2)
큰거 같다(>=)p1> = p2p1 __ ge __(p2)