소개
이 튜토리얼에서는 Python 의 기본적인 매직 메서드를 살펴보겠습니다. 매직 메서드는 "dunder" 메서드 (double underscore methods, 이중 밑줄 메서드) 라고도 하며, Python 객체가 특정 상황에서 어떻게 동작하는지 정의할 수 있게 해줍니다. 이를 통해 고급 및 사용자 정의 객체 조작이 가능해집니다.
이 튜토리얼에서는 Python 의 기본적인 매직 메서드를 살펴보겠습니다. 매직 메서드는 "dunder" 메서드 (double underscore methods, 이중 밑줄 메서드) 라고도 하며, Python 객체가 특정 상황에서 어떻게 동작하는지 정의할 수 있게 해줍니다. 이를 통해 고급 및 사용자 정의 객체 조작이 가능해집니다.
이 섹션에서는 Python 의 객체 초기화 및 표현 매직 메서드를 살펴보겠습니다. 이러한 메서드를 사용하면 객체를 생성하고 사람이 읽을 수 있고 모호하지 않은 문자열로 표현하는 사용자 정의 동작을 정의할 수 있습니다.
__init__ 메서드는 객체가 생성될 때 호출됩니다. 객체의 속성을 초기화하는 데 사용됩니다.
간단한 객체부터 시작해 보겠습니다. person.py에서 두 개의 속성을 가진 Person이라는 클래스를 생성합니다.
class Person:
def __init__(self, name: str, age: int):
"""
Initialize the Person object with a name and age.
:param name: The name of the person.
:param age: The age of the person.
"""
self.name = name
self.age = age
__str__ 메서드는 객체의 사람이 읽을 수 있는 문자열 표현을 얻기 위해 str() 내장 함수와 print() 함수에 의해 호출됩니다.
## ... (previous code in person.py)
def __str__(self) -> str:
"""
Return a human-readable string representation of the Person object.
:return: A string describing the person.
"""
return f"{self.name} is {self.age} years old."
__repr__ 메서드는 repr() 내장 함수에 의해 호출되며, 가능한 경우 객체를 다시 생성하는 데 사용할 수 있는 문자열 표현을 얻기 위해 대화형 인터프리터에서 사용됩니다.
## ... (previous code in person.py)
def __repr__(self) -> str:
"""
Return a string representation of the Person object that can be used to recreate the object.
:return: A string in the format 'Person(name, age)'.
"""
return f"Person('{self.name}', {self.age})"
이제 Person 클래스에 대한 기본 매직 메서드를 정의했으므로, init_repr_example.py에서 어떻게 작동하는지 살펴보겠습니다.
from person import Person
## Create a new Person object
p = Person("Alice", 30)
## Use the __str__ method with the print function
print(p) ## Output: Alice is 30 years old.
## Use the __repr__ method in the interactive interpreter
print(repr(p)) ## Output: Person('Alice', 30)
그런 다음 터미널에서 다음 명령을 입력하여 스크립트를 실행합니다.
python init_repr_example.py
이 섹션에서는 Python 에서 객체 비교에 사용되는 매직 메서드를 살펴보겠습니다. 이러한 메서드를 사용하면 클래스의 객체에 대한 사용자 정의 비교 로직을 정의할 수 있습니다.
__eq__ 메서드는 두 객체가 같은지 확인하는 데 사용됩니다. == 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __eq__(self, other: "Person") -> bool:
"""
Compare two Person objects for equality.
:param other: The other Person object to compare with.
:return: True if both objects have the same name and age, False otherwise.
"""
if isinstance(other, Person):
return self.name == other.name and self.age == other.age
return False
__ne__ 메서드는 두 객체가 같지 않은지 확인하는 데 사용됩니다. != 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __ne__(self, other: "Person") -> bool:
"""
Compare two Person objects for inequality.
:param other: The other Person object to compare with.
:return: True if the objects have different names or ages, False otherwise.
"""
return not self.__eq__(other)
__lt__ 메서드는 한 객체가 다른 객체보다 작은지 확인하는 데 사용됩니다. < 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __lt__(self, other: "Person") -> bool:
"""
Compare two Person objects to see if one is less than the other based on age.
:param other: The other Person object to compare with.
:return: True if the current object's age is less than the other object's age, False otherwise.
"""
if isinstance(other, Person):
return self.age < other.age
return NotImplemented
__le__ 메서드는 한 객체가 다른 객체보다 작거나 같은지 확인하는 데 사용됩니다. <= 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __le__(self, other: "Person") -> bool:
"""
Compare two Person objects to see if one is less than or equal to the other based on age.
:param other: The other Person object to compare with.
:return: True if the current object's age is less than or equal to the other object's age, False otherwise.
"""
if isinstance(other, Person):
return self.age <= other.age
return NotImplemented
__gt__ 메서드는 한 객체가 다른 객체보다 큰지 확인하는 데 사용됩니다. > 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __gt__(self, other: "Person") -> bool:
"""
Compare two Person objects to see if one is greater than the other based on age.
:param other: The other Person object to compare with.
:return: True if the current object's age is greater than the other object's age, False otherwise.
"""
if isinstance(other, Person):
return self.age > other.age
return NotImplemented
__ge__ 메서드는 한 객체가 다른 객체보다 크거나 같은지 확인하는 데 사용됩니다. >= 연산자에 의해 호출됩니다.
## ... (previous code in person.py)
def __ge__(self, other: "Person") -> bool:
"""
Compare two Person objects to see if one is greater than or equal to the other based on age.
:param other: The other Person object to compare with.
:return: True if the current object's age is greater than or equal to the other object's age, False otherwise.
"""
if isinstance(other, Person):
return self.age >= other.age
return NotImplemented
이제 Person 클래스에 대한 객체 비교 매직 메서드를 정의했으므로, compare_example.py에서 어떻게 작동하는지 살펴보겠습니다.
from person import Person
## Create two Person objects
p1 = Person("Alice", 30)
p2 = Person("Bob", 35)
## Use the __eq__ and __ne__ methods
print(p1 == p2) ## Output: False
print(p1 != p2) ## Output: True
## Use the __lt__, __le__, __gt__, and __ge__ methods
print(p1 < p2) ## Output: True
print(p1 <= p2) ## Output: True
print(p1 > p2) ## Output: False
print(p1 >= p2) ## Output: False
그런 다음 터미널에서 다음 명령을 입력하여 스크립트를 실행합니다.
python compare_example.py
이 섹션에서는 Python 의 객체 소멸 매직 메서드를 살펴보겠습니다. 이 메서드를 사용하면 객체가 소멸되기 전에 사용자 정의 동작을 정의할 수 있습니다.
__del__ 메서드는 객체가 소멸되기 직전에 호출됩니다. 객체가 가비지 수집되기 전에 파일 핸들을 닫거나 리소스를 해제하는 등 정리 작업을 수행할 수 있습니다.
## ... (previous code in person.py)
def __del__(self):
"""
Clean up the Person object before it is destroyed.
"""
print(f"Person '{self.name}' is being deleted.")
이제 Person 클래스에 대한 객체 소멸 매직 메서드를 정의했으므로, del_example.py에서 어떻게 작동하는지 살펴보겠습니다.
from person import Person
## Create a Person object and then delete it
p = Person("Alice", 30)
del p ## Output: Person 'Alice' is being deleted.
그런 다음 터미널에서 다음 명령을 입력하여 스크립트를 실행합니다.
python del_example.py
__del__ 메서드는 객체가 더 이상 필요하지 않을 때 즉시 호출되지 않을 수 있다는 점에 유의해야 합니다. 객체의 실제 삭제는 Python 인터프리터의 가비지 수집 메커니즘에 따라 달라집니다. __del__ 메서드는 가비지 수집기가 객체를 메모리에서 제거하기로 결정할 때 호출됩니다.
이 일련의 튜토리얼에서는 Python 의 매직 메서드, 즉 "dunder" 메서드 (이중 밑줄 메서드) 라고도 하는 메서드를 살펴보았습니다. 이러한 메서드를 사용하면 다양한 상황에서 객체에 대한 사용자 정의 동작을 정의할 수 있습니다.
이러한 매직 메서드를 마스터함으로써 더욱 강력하고 사용자 정의 가능한 Python 클래스와 객체를 만들 수 있습니다. 이러한 메서드를 이해하고 구현하면 더욱 효율적이고 깔끔하며 Pythonic 한 코드를 작성할 수 있으며, 프로그램의 견고성과 유지 관리성을 향상시킬 수 있습니다.