Python에서 기본 클래스의 클래스 메서드 호출


105

다음 코드를 고려하십시오.

class Base(object):

    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do(a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

> $ python play.py  
> In derived! 
> <class '__main__.Base'> msg

에서 Derived.do어떻게 전화 Base.do합니까?

super일반적인 개체 메서드 인 경우 일반적으로 또는 기본 클래스 이름을 직접 사용하지만 기본 클래스에서 classmethod를 호출하는 방법을 찾을 수 없습니다.

위의 예에서는 클래스 대신 클래스를 Base.do(a)인쇄합니다 .BaseDerived


답변:


121

새로운 스타일의 클래스를 사용하는 경우 (즉 object, Python 2 또는 항상 Python 3에서 파생 됨 ) 다음과 super()같이 할 수 있습니다 .

super(Derived, cls).do(a)

이것은 print cls, a파생 클래스 cls로 설정된 파생 클래스에서 기본 클래스 버전의 메서드 (예 :)에서 코드를 호출하는 방법 입니다.


8
어 .. super어째서 나도 수업 방법 에 사용할 수있는 일이 나에게 생기지 않았어 .
Sridhar Ratnakumar

이것은베이스가 객체에서 파생 된 경우에만 작동합니다 (super에 의해 부과 된 제한으로 인해), 맞습니까? 그렇지 않은 경우 어떻게합니까?
ars-longa-vita-brevis

예, 이것은 .NET에서 파생 된 새로운 스타일의 클래스에서만 작동합니다 object. (적어도 Python 2에서는, 그러나 Py3에서는 모든 클래스가 새로운 스타일, IIRC라고 생각합니다.) 그렇지 않으면 Base.do(self, ...), 제 생각에, 그렇게함으로써 수퍼 클래스의 이름을 하드 코딩해야합니다.
David Z

내부 Derived.do(), cls같지 Derived않습니까?
Ray

@Ray 그것이 실제로는 Derived서브 클래스 의 인스턴스가 아니라면, 그렇습니다.
David Z

15

오랜만에 답을 찾은 것 같습니다. 클래스 메서드가되도록 메서드를 장식하면 원래 바인딩되지 않은 메서드가 'im_func'라는 속성에 저장됩니다.

class Base(object):
    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do.im_func(cls, a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

2
참고 :이 접근 방식은 super ()가 작동하지 않는 이전 스타일 클래스에서 작동합니다
Alex Q

2
__func__파이썬 2.7 및 3 에서도 사용 가능
dtheodor 2014

-3

이것은 나를 위해 작동합니다.

Base.do('hi')

9
cls인수는 다음에 바인딩됩니다 Base대신Derived
스리 Ratnakumar

나를 위해 작동하는 것은 이것이 Ned의 대답과 비슷해 보입니다. 여기서 self는 paintEvent (QPaintEvent) def paintEvent (self, qpntEvent)가있는 QGraphicsView에서 파생됩니다 : print dir (self) QGraphicsView.paintEvent (self, qpntEvent)
user192127
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.