파이썬에서 멤버십 테스트 에뮬레이션 : __crantains __를 포함하여 포함하여 올바르게 관개합니다.

StackOverflow https://stackoverflow.com/questions/1022499

문제

나는 파이썬이 깔끔한 트릭이 다른 객체에 기능을 위임 할 수 있도록하는 데 익숙합니다. 한 가지 예는 포함 된 개체에 대한 대표단입니다.

그러나 __가 __을 대하기를 위임하고 싶을 때 운이 없다는 것은 이음새가 있습니다.

class A(object):
    def __init__(self):
       self.mydict = {}
       self.__contains__ = self.mydict.__contains__

a = A()
1 in a

나는 얻다:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'A' is not iterable

내가 무엇을 잘못 만들고 있습니까? a .__에 __ (1)을 포함한다고 부르면 모든 것이 부드러워집니다. 나는 심지어 __iter __ 메소드를 A의 반복적 인 것처럼 보이도록 정의하려고 노력했지만 도움이되지 않았습니다. 내가 여기서 놓친 것은 무엇입니까?

도움이 되었습니까?

해결책

다음과 같은 특별한 방법 __contains__ 인스턴스가 아닌 클래스에 정의 될 때만 특별합니다 (Python 2의 레거시 클래스 제외. ~ 아니다 어쨌든 사용).

따라서 수업 수준에서 대표단을 수행하십시오.

class A(object):
    def __init__(self):
       self.mydict = {}

    def __contains__(self, other):
       return self.mydict.__contains__(other)

나는 실제로 후자를 철자하는 것을 선호합니다 return other in self.mydict, 그러나 그것은 사소한 스타일의 문제입니다.

편집하다: "특별한 방법의 완전히 역동적 인 리디렉션"(구식 클래스와 같은)이 필수 불가결 한 경우, 새로운 스타일 클래스로 구현하기가 어렵지 않습니다. 독특한 필요가있는 각 인스턴스 만 필요합니다. 자체 특별 수업으로 싸여 있습니다. 예를 들어:

class BlackMagic(object):
    def __init__(self):
        self.mydict = {}
        self.__class__ = type(self.__class__.__name__, (self.__class__,), {})
        self.__class__.__contains__ = self.mydict.__contains__

본질적으로, 약간의 흑 마법이 재 할인 된 후 self.__class__ 새로운 클래스 객체 (이전 객체와 마찬가지로 동작하지만 공허한 덕트가 있고이 인스턴스가없는 다른 인스턴스가 없습니다. self), 당신이 할당 할 구식 수업의 어느 곳에서나 self.__magicname__, 할당 self.__class__.__magicname__ 대신 (그리고 그것이 내장인지 또는 staticmethod, 물론 다른 경우에 당신이 그것을 받기를 원하지 않는 한, 일반적인 파이썬 기능이 아닙니다. self 인스턴스에서 호출 될 때).

우연히도 in 이것의 인스턴스에서 연산자 BlackMagic 수업은 더 빠르게, 이전에 제안 된 솔루션보다, 또는 적어도 나는 평소 신뢰할 수있는 것으로 측정하고 있습니다. -mtimeit (직접 이동 built-in method, 상속 및 디스크립터와 관련된 일반적인 조회 경로를 따르지 않고 약간의 오버 헤드를 면도합니다).

자동화하는 메타 클래스 self.__class__-인스턴스 아이디어는 글을 쓰기가 어렵지 않습니다 (생성 된 클래스에서 더러운 작업을 수행 할 수 있습니다. __new__ 방법, 아마도 인스턴스에 할당 된 경우 모든 마법 이름을 실제로 클래스에 할당하도록 설정했을 수도 있습니다. __setattr__ 또는 많은, 많은 속성). 그러나이 기능의 필요성이 실제로 널리 퍼져있는 경우에만 정당화 될 것입니다 (예 : 파이썬 3을 포함한 현대 파이썬에 "인스턴스당 특별한 방법"을 자유롭게 사용하는 거대한 고대 Python 1.5.2 프로젝트를 포팅하는 경우).

내가 추천하다 "Clever"또는 "Black Magic"솔루션? 아니요, 나는하지 않습니다 : 거의 항상 간단하고 간단한 방식으로 일을하는 것이 좋습니다. 그러나 "거의"는 여기서 중요한 단어이며, 드문 일이지만 존재하지 않는 상황이 실제로 보증 될 수있는 진보 된 "고리"를 손에 넣는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top