파이썬 매직 메서드는 특수 메서드 또는 던더 메서드라고도합니다. __init__ ()와 같이 이중 밑줄로 둘러싸여 있습니다.
아래 코드 스니팻은 Human이라는 클래스를 만들어 human(소문자)으로 인스턴스화하여 진행할 부분입니다.
class Human :
def __init__ (self, id, name, addresses = [], maps = {}) :
self.id = id
self.name = name
self.addresses = addresses
self.maps = maps
만약 dir(human)
method를 실행해보면 29개의 메소드와 속성들이 리스팅 되고 그중 26개가 magic method
입니다
꽤 큰 비중을 차지하는 만큼 중요도도 높다고 봐요.
이 메서드는 클래스에서 속성을 삭제하려고 할 때 호출됩니다.
예를 들어, Human 객체 del first.name 에서 name 속성을 삭제하려면 __delattr__ () 메서드가 호출됩니다.
Human 클래스에서 메서드를 구현하여 기능을 재정의 할 수 있습니다.
def __delattr __ (self, item) :
print ( 'Deleting attribute'+ item)
return object .__ delattr __ (self, item)
output
del first.name
print (first.name)
# 속성 이름 삭제를 반환합니다.
print (first.name)
AttributeError : 'Human'개체에 'name'속성이 없습니다.
속성에 값을 할당하는 __setattr__ () 메서드와 속성에서 값을 가져 오는 __getattr__ () 메서드도 있습니다.
__delattr__ ()의 사용 사례는 객체의 특정 속성이 삭제되는 것을 방지하거나 특정 속성이 삭제 될 때 특정 작업을 수행하려는 경우 일 수 있습니다.
이 메서드는 개체를 나타내는 dictionay를 반환합니다. dictionay의 key는 객체의 속성이고 value는 해당 속성의 값입니다.
예를 들어 :
human = Human (2, 'Malik') .__ dict__
print (human)
output
{ 'id': 2, 'name': 'Malik', 'addresses': [], 'maps': {}}
클래스에서 __dir__ () 메서드를 재정 의하여 dir () 메서드를 재정의 할 수 있습니다. 예를 들어 dir () 메서드가 반환 한 결과에서 내부 메서드를 제거 할 수 있습니다.
def __dir __ (self) :
return list (filter (lambda x : not x.startswith ( '_'), object .__ dir __ (self)))
print (dir (human))
# [ 'addresses', 'id', 'maps', 'name']을 반환합니다.
이 메서드는 == 작업을 수행하려고 할 때 호출됩니다. 이름이 다르더라도 id 속성이 같을 때 두 human 객체가 같다고 생각해 봅시다.
이 기능을 달성하기 위해 __eq__ () 메서드를 재정의 할 수 있습니다.
first = Human (1, 'Farhad')
second = Human (1, 'Malik')
print (first == second)
# True
string.format ()을 시도 할 때마다 format () 메서드가 내부적으로 호출됩니다.
≥ 비교를 시도 할 때마다 ge() 메서드가 호출됩니다. __ge__() 구현하기 위해 커스터마이징하여 사용해 볼 게요
예를 들어 두 개의 Human 객체가 있다고 가정합니다.
first = Human(1, 'Farhad')
second = Human(2, 'Malik')
더 큰 Id를 가진 Human 객체가 다른 Human 객체보다 더 큰 것으로 간주된다는 규칙이 있다고 생각해 봅시다.
따라서 __gt__ () 메서드를 재정의하고 커스터마이징 로직을구현할 수 있습니다.
def __ge__(self, other) :
return self.id> = other.id
이제 두 번째 개체의 ID가 첫 번째 사람 개체보다 크기 때문에 False를 반환합니다.
print (first> = second)
False 반환
참고로, 연산자 ≤이 수행 될 때 실행되는 lt() 메서드도 있습니다.
해싱은 개체를 정수로 변환하는 데 사용됩니다. dictionary/set으로 항목을 설정하려고 할 때 해싱이 수행됩니다.
좋은 해싱 알고리즘은 더 적은 수의 해싱 충돌을 발생시킵니다. __hash__() 메서드를 재정의하여 자체 해시 알고리즘을 만들수 있어요.
Human 객체의 ID가 우리 애플리케이션에서 고유하다고 가정 해 봅시다. __hash__ () 알고리즘은 self.id를 해시 정수로 반환하도록 재정의 할 수 있습니다.
def __hash__(self):
return self.id
두 개의 개체를 만들어 집합 컬렉션에 저장할 수 있습니다. 집합의 길이를 쿼리 할 때 두 개체의 ID가 서로 다르기 때문에 집합에 두 개의 요소가 있어야합니다.
first = Human(1, 'Farhad')
second = Human(2, 'Malik')
my_set = set([first, second])
print(len(my_set))
#returns 2
이제 두 객체 모두에 대해 id를 1로 설정하고 연습을 반복하면 두 객체의 이름이 동일하더라도 동일한 해시 키를 가지기 때문에 집합에서 1 개의 요소 만 볼 수 있습니다. 속성이 다릅니다.
first = Human(1, 'Farhad')
second = Human(1, 'Malik')
my_set = set([first, second])
print(len(my_set))
#returns 1
__init__ () 메서드는 생성자를 호출하여 클래스의 새 인스턴스를 인스턴스화하려고 할 때 실행됩니다.
예를 들어 실행을 시도했을 때 :
human = Human(1, 'farhad')
__init__ () 메서드가 자동으로 실행됩니다.
사용자는 이 역시 아래와 같이 기능과 인자들을 커스터마이징 할 수 있어요.
예를 들어, Human 클래스의 __init__ () 메서드는 다음과 같습니다.
def __init__(self, id, name, addresses=[], maps={}):
self.id = id
self.name = name
self.addresses = addresses
self.maps = maps
이것은 메타 클래스 사용 사례 중 하나입니다. 클래스가 서브 클래화 되고 그 객체가 생성되면 __init_subclass__() 메서드가 호출됩니다.
기본적으로 메서드는 부모에게 하위 클래스가 지정되었음을 알립니다. 이러한 연결은 지정된 클래스의 모든 하위 클래스를 초기화 할 수 있습니다.
따라서이 메서드는 하위 클래스를 등록하고 하위 클래스의 속성에 기본값을 할당하는 데 사용됩니다. 따라서 하위 클래스 초기화를 사용자 정의로 지정 할 수 있습니다.
클래스의 새 인스턴스를 인스턴스화하고 생성하려면 __new__ (cls) 메서드가 실행됩니다.
__init__() 메서드는 __new__ () 메서드가 성공적으로 완료된 후에 실행됩니다.
__new__()는 클래스에 대한 정적 메서드입니다. 이는 메서드가 객체의 상태에 의존하지 않고 클래스 수준에 있음을 의미합니다.
예를 들어, Human() 생성자가 호출 될 때마다 'Human creating…'을 출력하고 싶다고 생각해 봅시다.
아래와 같이 __new__ (cls) 메서드의 기능을 재정의 할 수 있습니다.
def __new__(cls, *args, **kwargs):
print('Human creating...')
return object.__new__(cls)
결과적으로 Human creating …
은 인스턴스를 만들려고 할 때 인쇄됩니다.
human = Human(1, 'Farhad', ['Address1', 'Address1'], {'London':2, 'UK':3})
이 메서드는 sys.getsizeof ()를 실행할 때 호출됩니다. 메모리에있는 개체의 크기를 바이트 단위로 반환합니다.
__str__ () 메서드는 개체를 인쇄 가능한 형식으로 인쇄하려고 할 때 실행됩니다. str () 메서드의 기능을 재정의 할 수 있습니다.
예를 들어 :
class Human:
def __init__(self, id, name, addresses=[], maps={}):
self.id = id
self.name = name
self.addresses = addresses
self.maps = maps
def __str__(self):
return f'id={self.id}. name={self.name}'
human = Human(1, 'Farhad', ['Address1', 'Address1'], {'London':2, 'UK':3})
print(human)
id=1. name=Farhad.를 출력하게 되요.
__str__ () 함수는 사용자에게 친숙한 객체 표현을 반환해야합니다.
이 __weakref__ 객체는 대상 객체에 대한 weak references 리스트를 반환합니다. 기본적으로 가비지 수집이 참조가 수집되었음을 weak reference에 알리는 데 도움이됩니다.
따라서 기본 포인터에 액세스하는 개체를 방지합니다.
print(len(list(filter(lambda x: x.startswith('__') and x.endswith('__'), dir(human1.id)))))
이 메서드는 두 개의 숫자를 더하려고 할 때 호출됩니다.
예를 들어 :
human.id + 2는 human.id.__add__ (2)와 동일합니다.
또한 *를 수행 할 때 __mul__이 호출되고, '-'연산자를 사용할 때 __sub__가 호출되고, / 연산자를 사용하려고하면 __div__가 실행됩니다.
이 메소드는 & 연산자를 사용하려고 할 때 실행됩니다. 예 :
self & another_value 반환
이 메소드는 객체에 대해 부울 검사를 수행하려고 할 때 실행됩니다.
자기! = 123
이 메서드는 // operator를 실행할 때 실행됩니다.
__getnewargs__
때때로 우리는 파이썬에서 객체를 피클합니다. 피클 링은 필요한 경우 디스크에 저장할 수있는 메모리에있는 개체의 바이트 스트림 표현을 만듭니다.
__getnewargs__() 메서드는 피클 링 프로세스에 피클 링 된 개체를 다시로드하여 대상 개체를 다시 만드는 방법을 알려줍니다. 특히 new () 메서드에 인수를 전달하여 객체를 만드는 방법입니다. 따라서 이름은 ' get new args'입니다.
__index__
이 메소드는 객체를 인덱스로 사용하려고 할 때 실행됩니다. 예를 들어 my_list [0]을 실행하려고하면 my_list [0 . index ()]와 동일합니다.
결과적으로 index () 메서드를 실행하여 객체를 정수로 변환 할 수 있습니다. 또한 메서드를 재정의하고 인덱스 생성 방법에 대한 자체 기능을 제공 할 수도 있습니다.
__invert__
이 메서드는 ~ 연산자를 사용할 때 실행됩니다.
예를 들어 :
first = Human(1, 'Farhad')
print(first.id.__invert__())
다음을 실행하는 것과 동일합니다.
first = Human (1, 'Farhad')
print (first.id .__ invert __ ())
이 방법은 값의 왼쪽 이동을 제공합니다 (예 : self << value). lshift () 메서드를 재정 의하여 << 연산자를 오버로드 할 수 있습니다.
참고 : rshift ()는 >> 연산자를 수행 할 때 실행됩니다.
이 메서드는 % 연산자를 사용할 때 호출됩니다.
이 메서드는 부정 연산자를 사용할 때 실행됩니다.
first.id — second.id
이 메서드를 재정의하여 issubclass() 메서드를 사용자 지정할 수 있습니다. 기본적으로 클래스가 하위 클래스이면 True를 반환하고 그렇지 않으면 False를 반환합니다. 이 메서드는 기존 알고리즘을 사용할 수 있도록하는 NotImplemented도 반환합니다.
이 메서드는 issubclass () 메서드의 결과를 사용자 지정할 수 있습니다.
사람의 이름 속성이 문자열 유형임을 알 수 있습니다. 그런 다음 속성에 대해 dir (human.name)을 수행하고 이중 밑줄로 둘러싸인 메서드를 필터링하면 총 33 개의 매직 메서드가 있음을 알 수 있습니다.
print(len(list(filter(lambda x: x.startswith('__') and x.endswith('__'), dir(human1.name)))))
이 메소드는 주어진 캐릭터가 존재하는지 확인하려고 할 때 실행됩니다.
이 메서드는 문자열의 길이를 반환합니다. len () 메서드를 수행 할 때 실행됩니다.
문자열의 길이를 계산하기 위해 특정 문자 만 계산하려면 해당 기능을 제공하기 위해 __()__ 메서드를 재정의 할 수 있습니다.
이 메서드는 객체의 개발자 친화적 인 표현을 만들고 싶을 때 실행됩니다.
클래스에 __str__ () 구현이 없으면 print(object) 때 __repr__이 실행됩니다.
def __repr__(self):
return f'id={self.id} ({type(self.id)}). name={self.name} ({type(self.name)})'
print(Human(1, 'Farhad'))
output
id=1 (<class ‘int’>). name=Farhad (<class ‘str’>)
__repr__ () 메서드는 객체의 공식적인 표현을 생성하기위한 것이어야합니다.
때때로 할당과 함께 더하기 연산자를 사용합니다.
self.id + = 1
이것은 self.id = self.id + 1과 같습니다.
iadd() 메서드는 할당과 함께 add를 할 때 실행됩니다.
곱셈과 할당을 수행 할 때 __imul__ ()이 실행되고-=를 사용할 때 __isub__ ()가 실행되고 /=를 실행할 때 __idiv__() 메서드가 실행된다는 점에 유의하는 것이 중요합니다.
또한 **=가 수행되면 __ipow__ () 메서드가 실행됩니다.
__iand__ () 매직 메서드는 할당과 함께 비트 AND를 수행하기위한 것이며 __ior __ ()는 다음과 같이! 를 시도 할 때 호출됩니다. i! = j
human 객체의 address 속성은 list 타입입니다. 그런 다음 addresses 속성에서 dir (human.addresses)를 수행하고 이중 밑줄로 둘러싸인 메서드를 필터링하면 총 35 개의 매직 메서드가 있음을 알 수 있습니다.
print(len(list(filter(lambda x: x.startswith('__') and x.endswith('__'), dir(human1.addresses)))))
객체가 피클되면 reduce () 메서드가 실행되어 피클이 객체를 다시 생성하는 방법을 이해하는 데 도움이되는 객체를 반환합니다.
__reduce_ex__ () 메서드는 __reduce__ () 메서드보다 pickle에 의해 선호됩니다.
__reduce_ex__ () 메서드는 프로토콜 버전 인 정수 인수를 사용합니다. 피클 링에 대한 이전 버전과의 호환성을 제공하며 피클 된 바이트 스트림을 객체에 구성하는 데 사용됩니다.
__reversed__ () 메서드는 컬렉션을 역순으로 되돌리려 고 할 때 실행됩니다.
reversed (collection) 또는 collection.reverse ()가 호출되면 실행됩니다. 때로는 reversed () 메서드의 기능을 변경하기로 결정합니다.
__reversed__ () 메서드를 재정의하면 원하는 결과를 얻을 수 있습니다.
print(len(list(filter(lambda x: x.startswith('__') and x.endswith('__'), dir(human1.maps)))))
이 메소드는 항목을 삭제할 때 실행됩니다.
del dictionary[key]
이 메서드는 키에 대한 항목을 가져 오려고 할 때 실행됩니다.
item = dictionary[key]
이 메서드는 사전에 항목을 설정하려고 할 때 실행됩니다.
dictionary[key] = item
이 메서드는 컬렉션의 반복자를 반환합니다. 반복자는 컬렉션을 반복하는 데 도움이됩니다.
__iter__ () 메서드를 재정 의하여 iterator()가 실행되는 방식을 재정의 할 수 있습니다.
마지막으로 __call__()에 대한 참고 사항
객체를 호출 가능하게 만들고 싶다면?
human() 함수로 만들고 싶다고 생각해 봅시다.
__call__ () 메서드를 사용하면 클래스를 함수로 취급 할 수 있습니다.
human = Human(1, 'Farhad')
human()
Human 클래스에서 __call__ () 매직 메서드 구현한다면 의도한 기능을 만들어 낼 수 있어요.
def __repr__(self):
return f'id={self.id} ({type(self.id)}). name={self.name} ({type(self.name)})'
def __call__(self, *args, **kwargs):
print('You attempted to call')
print('Arguments: ', args)
print('Keyword Arguments: ', kwargs)
print(self)
print('Call completed')
output
You attempted to call
Arguments: ()
Keyword Arguments: {}
id=1 (<class ‘int’>). name=Farhad (<class ‘str’>)
Call completed
__call__ () 메서드를 재정의함으로써 이제 데코레이터를 구현하여 객체를 함수로 반환하거나 실제 객체를 전달하여 함수를 인수로 받아들이는 라이브러리를 호출 할 수도 있습니다.
참고:medium.com
Las Vegas is home to some of the world’s most exciting and talented performers, and magicians are no exception. If you're seeking top-tier magical entertainment, you can't go wrong with a Las Vegas magician. With dazzling illusions, sleight-of-hand tricks, and mind-blowing performances, these entertainers captivate audiences of all ages. Whether you're visiting the Strip or planning a special event, you can find exceptional magicians to elevate the experience. A great place to explore options is las vegas magician where you'll discover a performer known for her enchanting, interactive shows that leave lasting impressions on her audience.