2011-02-03 10 views
8

하위 클래스의 메서드를 재정의 할 때 나는 종종 이렇게 :바로 가기

def method_x(self): 
    x = super(type(self), self).method_x() 

    [Some extra code] 
    return x 

내 질문은 : 짧은 슈퍼에 대한 컷 (유형 (자기가 거기에) , 자기)?

+14

위의 코드를 읽는 사람에게 경고 : * wrong *. 그것을 모방하지 마십시오! –

+0

Glenn, Duncan :이 점을 지적 해 주셔서 감사합니다. 내 코드를 grep하고이를 변경해야 할 것이다. –

+0

@ 글렌 메이 너드 : 당신이 왜 잘못 생각했는지 모르겠다. 'super (self .__ class__, self) '를 사용해도 좋을까요? – martineau

답변

17

이렇게하지 마십시오. super이 첫 번째 인수로 type(self)을 사용할 수 있다면 처음에는 두 개의 인수를 사용하도록 작성되지 않았을 것입니다. 클래스가 서브 클래스화된 경우 변경할 수있는 표현식이 아닌 실제 클래스를 여기에 전달해야합니다.

super에 대한 첫 번째 인수는 검색을 시작할 기지 목록에서 super를 말하면서 현재 메소드 정의를 포함하는 클래스 여야합니다.

파이썬 3은 이것을 알고 컴파일시에 super()을 마술처럼 취급하지만, 파이썬 2.x에서는 단지 일반적인 함수이므로 그 자체에 대한 매개 변수를 알아낼 방법이 없습니다.

[내 첫 부분에 추가하려면 수정] 사실, 파이썬 2.x에서 super()을 사용하는 덜 사용되는 방법이 있습니다. 당신이 그것을 액세스 할 때 당신은 슈퍼 언 바운드 폼을 사용하고 결합 할 수 있습니다 :

>>> class A(object): 
    def foo(self): 
     print "A.foo" 


>>> class B(A): 
    def foo(self): 
     self.__super.foo() 
     print "B.foo" 


>>> B._B__super = super(B) 
>>> class C(A): 
    def foo(self): 
     self.__super.foo() 
     print "C.foo" 


>>> C._C__super = super(C) 
>>> class D(C,B): pass 

>>> D._D__super = super(D) 
>>> D().foo() 
A.foo 
B.foo 
C.foo 

여기서 중요한 캐치가있다 : 당신은 당신이 사용 할 수있는 각 super 객체를 저장하기 위해 다른 이름을 사용해야합니다 self.__super이지만 아직 클래스 정의에 바인딩되지 않은 super을 만들 수는 없습니다 (클래스가 아직 존재하지 않으면 이름을 지정할 수 없기 때문에). 외부에 만들면 올바른 이름을 설정하기 위해 수동으로 이름을 난독 화해야합니다. __super 클래스의 개체입니다. Python 2.6 이상에서는 이것을 클래스 데코레이터로 사용할 수 있습니다.

+1

권장 사항을 권장하지 않습니다. 그렇게 특이한 일을하는 것은별로 승리하지 않습니다. –

+2

네, 어쩌면 덜 사용되는 지저분하지만, 제가 옵션으로 언급해야한다고 생각했습니다. 훨씬 더 좋은 옵션은 파이썬 3.x를 사용하는 것입니다. (필요한 라이브러리를 지원해야합니다) – Duncan

+0

오늘 파이썬 3을 사용하여 보았습니다. 나는 Pylons Pyramid를 사용하고 있으며 일부는 py3을 아직 지원하지 않으므로 몇 달 후에 다시 확인해야합니다. –