Python의 마법 방법 IV

2024. 4. 11. 07:55python/advanced

회원 운영자

Python에는 주어진 값이 값 모음에 있는지 여부를 확인할 수 있는 두 가지 연산자가 있습니다. 두 가지 연산자는 in 및 not in 입니다. 멤버십 테스트라고 알려진 검사를 지원합니다.

예를 들어, 숫자 목록에 숫자가 나타나는지 확인하려고 한다고 가정해 보겠습니다. 다음과 같이 할 수 있습니다:

In [ ]:
2 in [2, 3, 5, 9, 7]
In [ ]:
10 in [2, 3, 5, 9, 7]

첫 번째 예에서는 숫자 2가 숫자 목록에 있으므로 True 결과를 얻습니다. 두 번째 예에서는 숫자 10이 목록에 없으므로 False을 얻습니다. not in 연산자는 in과 유사하지만 부정으로 작동합니다. 이 연산자를 사용하면 주어진 값이 컬렉션에 없는지 확인할 수 있습니다.

멤버십 연산자 in과 not in을 지원하는 특수 메소드는 .contains() 입니다. 사용자 정의 클래스에서 이 메서드를 구현하면 해당 인스턴스가 멤버십 테스트에서 작동하는 방식을 제어할 수 있습니다.

.contains() 메서드는 확인하려는 값을 나타내는 인수를 가져와야 합니다.

사용자 정의 클래스에서 멤버십 테스트를 지원하는 방법을 설명하기 위해 in과 not in 연산자와 마찬가지로 일반적인 푸시 및 팝 작업을 지원하는 기본 스택 데이터 구조를 구현한다고 가정해 보겠습니다.

Stack class 코드는 다음과 같습니다.

(참고) 아래 코들르 stack.py으로 저장하세요.

In [ ]:
class Stack:
    def __init__(self, items=None):
        self.items = list(items) if items is not None else []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def __contains__(self, item):
        for current_item in self.items:
            if item == current_item:
                return True
        return False

이 예에서는 Stack을 정의하고 .push() 및 .pop() 메서드를 제공합니다. 전자의 메서드는 스택 맨 위에 새 항목을 추가하는 반면, 후자의 메서드는 스택 맨 위에 있는 항목을 제거하고 반환합니다.

그런 다음 대상 항목을 인수로 사용하고 for 루프를 사용하여 해당 항목이 스택의 데이터를 저장하는 목록에 있는지 확인하는 .contains() 메서드를 구현합니다.

참고:in 연산자 자체를 활용하면 위의 .contains() 구현을 더욱 간결하게 만들 수 있습니다. Python 목록은 기본적으로 멤버십 테스트를 지원하기 때문에 가능합니다.

예를 들어 다음과 같은 작업을 수행할 수 있습니다.

# stack.py

class Stack:
     # ...

     def contains(self, item):
         return item in self.items

.contains()의 이 버전에서는 for 루프 대신 in 연산자를 사용합니다. 따라서 데이터를 명시적으로 반복하지 않고 멤버십을 직접 확인합니다.

멤버십 테스트에서 Stack 인스턴스를 사용하는 방법은 다음과 같습니다.

In [ ]:
from stack import Stack

stack = Stack([2, 3, 5, 9, 7])

2 in stack
In [ ]:
10 in stack
In [ ]:
2 not in stack
In [ ]:
10 not in stack

사용자 정의 클래스에 .contains() 메서드를 구현하면, 해당 클래스의 개체가 in 및 not in 연산자를 사용하여 멤버십 확인에 응답하는 방식을 사용자 정의할 수 있습니다.

비트 연산자

Python의 비트 연산자를 사용하면 가장 세부적인 수준에서 개별 데이터 비트를 조작할 수 있습니다. 이러한 연산자를 사용하면 비트별 AND, OR, XOR, NOT 및 비트 시프트 연산을 수행할 수 있습니다. 이러한 연산자는 특별한 방법을 통해서도 구현됩니다.

다음은 Python의 비트 연산자와 지원 방법에 대한 요약입니다.

|운영자|지원방법| |---|---| |&|.__and__(self, other)| |||.__or__(self, other)| |^|.__xor__(self, other)| |<<|.__lshift__(self, other)| |>>|.__rshift__(self, other)| |~|.__invert__()|

이러한 메서드를 사용하면 사용자 정의 클래스가 비트 연산자를 지원하도록 할 수 있습니다. 다음 장난감 예를 고려하십시오.

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

class BitwiseNumber: def init(self, value): self.value = value

def __and__(self, other):
    return type(self)(self.value & other.value)

def __or__(self, other):
    return type(self)(self.value | other.value)

def __xor__(self, other):
    return type(self)(self.value ^ other.value)

def __invert__(self):
    return type(self)(~self.value)

def __lshift__(self, places):
    return type(self)(self.value << places)

def __rshift__(self, places):
    return type(self)(self.value >> places)

def __repr__(self):
    return bin(self.value)

사용자 정의 클래스 BitwiseNumber에서 필요한 메소드를 구현하려면 현재 메소드에 해당하는 비트 연산자를 사용하십시오. .__and__(), .__or__() 및 .__xor__() 메소드는 현재 BitwiseNumber 인스턴스의 값과 other에서 작동합니다. 이 두 번째 피연산자는 BitwiseNumber의 또 다른 인스턴스여야 합니다.

.invert() 메서드는 단일 피연산자에 대해 작동하므로 단항 연산자인 비트별 NOT 연산자를 지원합니다. 따라서 이 메서드는 두 번째 인수를 사용하지 않습니다.

마지막으로 비트 시프트 연산자를 지원하는 두 가지 메서드는 places라는 인수를 사용합니다. 이 인수는 어느 방향으로든 비트를 이동하려는 위치 수를 나타냅니다.

참고: BitwiseNumbe에서는 이러한 메소드 유형에 대한 지침을 따르지 않는 .repr() 메소드를 코딩했습니다. 그 목적은 REPL 세션에서 클래스가 어떻게 작동하는지 보여주는 빠른 표현을 제공하는 것입니다. 아래 예를 참조하세요.

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

In [ ]:
from bitwise_number import BitwiseNumber

five = BitwiseNumber(5)
ten = BitwiseNumber(10)

# Bitwise AND
#    0b101
# & 0b1010
# --------
#      0b0
five & ten
In [ ]:
# Bitwise OR
#    0b101
# | 0b1010
# --------
#   0b1111
five | ten
In [ ]:
five ^ ten
In [ ]:
~five
In [ ]:
five << 2
In [ ]:
ten >> 1

BitwiseNumber가 예상대로 작동합니다. 모든 비트 연산자를 지원하며 매번 예상되는 비트를 반환합니다.

 

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

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

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