제자리 연산
제자리 연산은 새로운 객체를 생성하지 않고 객체의 값을 제자리에서 수정하는 연산입니다. +=, -=, *=, /= 등과 같은 확장 할당 연산자로 표시됩니다.
Python 클래스에 대해 제자리 연산자가 정의되지 않은 경우, 제자리 연산을 시도하면 대신 이항 연산자가 사용됩니다.
inplace_example1.py에 예시가 있습니다. 이항 연산자를 제자리 연산자로 변경합니다.
from number import MyNumber
## Create two new MyNumber objects
a = MyNumber(5)
b = MyNumber(3)
print(f'{a.value=}, {b.value=}') ## Output: a.value=5, b.value=3
a += b
## Use the __add__ method with the print function
print(f'after a+=b: {a.value=}') ## Output:after a+=b: (a+b).value=8
예제를 실행하려면 터미널에 다음 명령을 입력합니다.
python inplace_example1.py
결과에서 += 연산을 시도했을 때 __add__가 사용되었음을 보여줍니다.
그런 다음 MyNumber에서 제자리 연산을 구현하고 해당 이항 연산자와의 동작이 약간 다릅니다.
__iadd__
__iadd__ 매직 메서드는 제자리 덧셈 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 += 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __iadd__(self, other: 'MyNumber') -> 'MyNumber':
"""Adds the other instance's value to the instance's value in-place."""
print(f'input: {self.value=}, {other.value=}')
self.value += other.value
print(f'after +=: {self.value=}')
return self
__isub__
__isub__ 매직 메서드는 제자리 뺄셈 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 -= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __isub__(self, other: 'MyNumber') -> 'MyNumber':
"""Subtracts the other instance's value from the instance's value in-place."""
print(f'input: {self.value=}, {other.value=}')
self.value -= other.value
print(f'after -=: {self.value=}')
return self
__imul__
__imul__ 매직 메서드는 제자리 곱셈 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 *= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __imul__(self, other: 'MyNumber') -> 'MyNumber':
"""Multiplies the instance's value by the other instance's value in-place."""
print(f'input: {self.value=}, {other.value=}')
self.value *= other.value
print(f'after *=: {self.value=}')
return self
__itruediv__
__itruediv__ 매직 메서드는 제자리 참 나눗셈 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 /= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __itruediv__(self, other: 'MyNumber') -> 'MyNumber':
"""Divides the instance's value by the other instance's value in-place."""
print(f'input: {self.value=}, {other.value=}')
self.value /= other.value
print(f'after /=: {self.value=}')
return self
__ifloordiv__
__ifloordiv__ 매직 메서드는 제자리 정수 나눗셈 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 //= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __ifloordiv__(self, other: 'MyNumber') -> 'MyNumber':
"""Performs in-place floor division on the instance's value by the other instance's value."""
print(f'input: {self.value=}, {other.value=}')
self.value //= other.value
print(f'after //=: {self.value=}')
return self
__imod__
__imod__ 매직 메서드는 제자리 모듈로 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 %= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __imod__(self, other: 'MyNumber') -> 'MyNumber':
"""Performs in-place modulo operation on the instance's value by the other instance's value."""
print(f'input: {self.value=}, {other.value=}')
self.value %= other.value
print(f'after %=: {self.value=}')
return self
__ipow__
__ipow__ 매직 메서드는 제자리 거듭제곱 연산이 어떻게 동작해야 하는지 정의합니다. 클래스 인스턴스에 **= 연산자를 사용하면 이 메서드가 호출됩니다.
## ... (previous code in number.py)
def __ipow__(self, other: 'MyNumber') -> 'MyNumber':
"""Raises the instance's value to the power of the other instance's value in-place."""
print(f'input: {self.value=}, {other.value=}')
self.value **= other.value
print(f'after **=: {self.value=}')
return self
예시: 제자리 연산 사용
MyNumber 클래스에 대한 제자리 연산자를 정의했으므로, inplace_example2.py에서 어떻게 작동하는지 살펴보겠습니다.
from number import MyNumber
## Create a new MyNumber objects
a = MyNumber(13)
## Use the __iadd__ method
a += MyNumber(5)
## Output:
## input: self.value=13, other.value=5
## after +=: self.value=18
## Use the __isub__ method
a -= MyNumber(5)
## Output:
## input: self.value=18, other.value=5
## after -=: self.value=13
## Use the __imul__ method
a *= MyNumber(5)
## Output:
## input: self.value=13, other.value=5
## after *=: self.value=65
## Use the __itruediv__ method
a /= MyNumber(5)
## Output:
## input: self.value=65, other.value=5
## after /=: self.value=13.0
## Use the __ifloordiv__ method
a //= MyNumber(2)
## Output:
## input: self.value=13.0, other.value=2
## after //=: self.value=6.0
## Use the __imod__ method
a %= MyNumber(4)
## Output:
## input: self.value=6.0, other.value=4
## after %=: self.value=2.0
## Use the __ipow__ method
a **= MyNumber(3)
## Output:
## input: self.value=2.0, other.value=3
## after **=: self.value=8.0
그런 다음 터미널에서 다음 명령을 입력하여 스크립트를 실행합니다.
python inplace_example2.py