2013-02-09 1 views
2

에서 init__ .__ 통화 유니 코드가 나는 상황이 발생 한 경우 파이썬에 대한 사용 중단 경고 이전에 파이썬 3.3에서 3.3로 오류의 하위 클래스 유니 코드 결과 :방법 (또는 왜 안) 서브 클래스

# prove that unicode.__init__ accepts parameters 
s = unicode('foo') 
s.__init__('foo') 
unicode.__init__(s, 'foo') 

class unicode2(unicode): 
    def __init__(self, other): 
     super(unicode2, self).__init__(other) 

s = unicode2('foo') 

class unicode3(unicode): 
    def __init__(self, other): 
     unicode.__init__(self, other) 

s = unicode3('foo') 

호기심의 경고/에러는 처음 세 줄에서는 발생하지 않고, 대신에 8 번과 14 번 줄에서 발생합니다. 파이썬 2.7의 결과는 다음과 같습니다.

> python -Wd .\init.py 
.\init.py:8: DeprecationWarning: object.__init__() takes no parameters 
    super(unicode2, self).__init__(other) 
.\init.py:14: DeprecationWarning: object.__init__() takes no parameters 
    unicode.__init__(self, other) 

코드는 간략하게 설명되어 있습니다. 실제 응용 프로그램에서는 단순히 수퍼 전화 __init__을 호출하는 것 이상의 작업을 수행 할 것입니다.

그것은 유니 __init__ 클래스를 구현하는 첫 번째 세 라인으로부터 나타나고 그 방법은 적어도 하나의 매개 변수를 수용한다. 그러나 서브 클래스에서 해당 메서드를 호출하려면 super()을 호출하는지 여부에 관계없이이를 수행 할 수없는 것으로 보입니다.

왜 유니 코드 인스턴스가 아니라 유니 코드의 서브 클래스에 unicode.__init__를 호출 괜찮습니다? 유니 코드 클래스를 서브 클래 싱하는 경우 작성자는 무엇을해야합니까?

+1

문자열을 하위 클래스로 분류한다고 생각하지 않습니다 ... 내부적으로 유니 코드 문자열을 사용하여 사용자 지정 클래스를 만들 수없는 특별한 이유가 있습니까? 객체를 유니 코드 문자열처럼 쉽게 걷고 말하게 할 수 있습니다. – Hubro

+0

왜 문제가 발생하는지 모르겠지만 유니 코드를 서브 클래 싱하는 것은 정말 이례적인 것처럼 보입니다. –

+1

완벽한 세계에서 어떤 객체라도 서브 클래스 할 수 있어야합니다. 문자열을 서브 클래 싱하는 것은 특히 서브 클래스가 _as_ 문자열을 사용해야 할 때 유용합니다. 문자열의 모든 인터페이스를 에뮬레이션하려고하면 간단히 서브 클래 싱하는 것보다 훨씬 어렵고 오류가 발생하기 쉽습니다. 예를 들어, 하위 클래스 화없이'isinstance (my_subclass_instance, basestring) '에 대해 true를 반환하도록 클래스를 구현하는 방법은 무엇입니까? https://bitbucket.org/yougov/pmxbot/src/6415472739/pmxbot/core.py#cl-48 및 https://github.com/jaraco/path.py/blob/ba38fc205e/path.py#L106을 참조하십시오. 유용한 예제. –

답변

4

나는 문제가 unicode 불변이라는 사실에서 오는 생각한다. unicode 인스턴스가 생성

후에는 수정 될 수 없다. 따라서 모든 초기화 논리는 __init__ (인스턴스가 존재 한 후에 만 ​​호출 됨) 대신 __new__ 메서드 (인스턴스 생성을 수행하기 위해 호출 됨)에 있습니다.

불변 유형의 하위 클래스에는 똑같은 엄격한 요구 사항이 없으므로 원하는 경우 unicode2.__init__에서 작업을 수행 할 수 있지만 unicode.__init__을 호출하는 것은 불필요합니다 (어쨌든 그렇게 할 것이라고 생각하지는 않음) .

더 나은 솔루션은 자신의 __new__ 방법으로 사용자 정의 된 로직을 수행하는 아마 : 당신이 원하는 경우

class unicode2(unicode): 
    def __new__(cls, value): 
     # optionally do stuff to value here 
     self = super(unicode2, cls).__new__(cls, value) 
     # optionally do stuff to self here 
     return self 

당신은 그것을 항상 예외를 발생시키는 __setattr__ 방법을 제공함으로써, 너무 불변의 클래스를 만들 수 있습니다 인스턴스 당 __dict__을 생략하여 메모리를 절약하려면 클래스에 __slots__ 속성을 제공 할 수도 있습니다.

+1

좋은 대답이지만 yoeur 예제는'str2'를'unicode2'로 대체해야합니다. 아니면 그냥 'unicode .__ new __ (cls, ...')로 직접 호출하십시오. – Keith

+0

아, 그건 내가 시도한 파이썬 3 구현에서 복사 한 오타입니다 (거기에 '유니 코드'클래스가 없습니다). 나는 갱신 할 것이다. – Blckknght

+0

답변 주셔서 감사합니다. 그러나 유니 코드 인스턴스에서'__init__ '을 호출 할 수 있지만 유니 코드 - 서브 클래스 인스턴스에서는 호출 할 수없는 이유를 설명하지는 않습니다. 유니 코드는 불변이지만,'__init__ '중에 어떤 것이 일어난다는 것은 여전히 ​​상상할 수 있습니다. 기본 구현에 대한 지식이 없으면 처음 세 줄의 코드를 실행하여 'unicode .__ init__'이 존재하고 매개 변수를 받아들이는 것으로 확인되어 하위 클래스에서 해당 메서드를 억제하지 않으려합니다. 문제는 유니 코드를 하위 클래스 화하는 방법을 묻는 것이 아니라 하위 클래스에서만'unicode .__ init__ '이 작동하지 않는 이유입니다. –