development

파이썬에서 자식 클래스에서 부모 클래스의 메소드를 호출 하시겠습니까?

big-blog 2020. 2. 10. 22:15
반응형

파이썬에서 자식 클래스에서 부모 클래스의 메소드를 호출 하시겠습니까?


파이썬에서 간단한 객체 계층을 만들 때 파생 클래스에서 부모 클래스의 메서드를 호출 할 수 있기를 원합니다. Perl 및 Java에는이 키워드 ( super)에 대한 키워드가 있습니다. Perl에서는 다음과 같이 할 수 있습니다.

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
   my $str = SUPER::frotz();
   return uc($str);
}

파이썬에서는 자식 클래스의 부모 클래스 이름을 명시 적으로 지정해야합니다. 위의 예에서와 같은 작업을 수행해야합니다 Foo::frotz().

이 동작은 깊은 계층 구조를 만들기가 어렵 기 때문에 옳지 않은 것 같습니다. 아이들이 상속 된 메소드를 정의한 클래스를 알아야하는 경우 모든 종류의 정보 고통이 발생합니다.

이것은 파이썬의 실제 제한입니까, 내 이해의 차이 또는 둘 다입니까?


네,하지만 새로운 스타일의 클래스 에서만 가능 합니다. super()기능을 사용하십시오 :

class Foo(Bar):
    def baz(self, arg):
        return super(Foo, self).baz(arg)

Python 3.x의 경우 다음을 사용할 수 있습니다.

class Foo(Bar):
    def baz(self, arg):
        return super().baz(arg)

파이썬에는 슈퍼 도 있습니다.

super(type[, object-or-type])

메서드 호출을 부모 또는 형제 유형의 클래스에 위임하는 프록시 객체를 반환합니다. 클래스에서 재정의 된 상속 된 메서드에 액세스하는 데 유용합니다. 검색 순서는 유형 자체를 건너 뛰는 것을 제외하고 getattr ()에서 사용 된 것과 동일합니다.

예:

class A(object):     # deriving from 'object' declares A as a 'new-style-class'
    def foo(self):
        print "foo"

class B(A):
    def foo(self):
        super(B, self).foo()   # calls 'A.foo()'

myB = B()
myB.foo()

ImmediateParentClass.frotz(self)

직계 부모 클래스가 frotz자체적으로 정의했는지 아니면 상속 했는지에 관계없이 괜찮 습니다. 다중 상속 super을 올바르게 지원하는 데만 필요합니다 (그리고 모든 클래스가 올바르게 사용하는 경우에만 작동합니다). 일반적으로 정의하지 않거나 재정의하지 않으면 조상 을 찾아 볼 것 입니다. 이것은 "자식을 호출하는 부모 클래스의 메소드"에 대해서도 마찬가지입니다.AnyClass.whateverwhateverAnyClassAnyClass


파이썬 3 은 부모 메소드를 호출하기위한 다른 간단하고 간단한 구문을 가지고 있습니다.

Foo클래스가에서 상속받은 경우 Bar다음 Bar.__init__Foo통해 from 호출 할 수 있습니다 super().__init__().

class Foo(Bar):

    def __init__(self, *args, **kwargs):
        # invoke Bar.__init__
        super().__init__(*args, **kwargs)

많은 답변이 자식에서 재정의 된 부모로부터 메서드를 호출하는 방법을 설명했습니다.

하나

"자식 클래스에서 부모 클래스의 메소드를 어떻게 호출합니까?"

또한 의미 할 수 있습니다 :

"상속 된 메소드를 어떻게 호출합니까?"

덮어 쓰지 않는 한 자식 클래스의 메서드 인 것처럼 부모 클래스에서 상속 된 메서드를 호출 할 수 있습니다.

예를 들어 파이썬 3 :

class A():
  def bar(self, string):
    print("Hi, I'm bar, inherited from A"+string)

class B(A):
  def baz(self):
    self.bar(" - called by baz in B")

B().baz() # prints out "Hi, I'm bar, inherited from A - called by baz in B"

그렇습니다. 이것은 상당히 분명 할 수 있지만 사람들이 지적하지 않으면 사람들이 파이썬에서 상속 된 메소드에 액세스하기 위해 어리석은 농구 대를 뛰어 넘어야한다는 인상을 남길 수 있다고 생각합니다. 특히이 질문은 "파이썬에서 부모 클래스의 메소드에 액세스하는 방법"에 대한 검색에서 높은 평가를 받고 OP는 파이썬을 처음 접하는 사람의 관점에서 작성됩니다.

상속 된 메소드에 액세스하는 방법을 이해하는 데 유용한 https://docs.python.org/3/tutorial/classes.html#inheritance찾았습니다 .


다음은 super () 사용 예입니다 .

#New-style classes inherit from object, or from another new-style class
class Dog(object):

    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self):
        self.moves.append('walk')
        self.moves.append('run')

    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super(Superdog, self).moves_setup()
        self.moves.append('fly')

dog = Superdog('Freddy')
print dog.name # Freddy
dog.moves_setup()
print dog.get_moves() # ['walk', 'run', 'fly']. 
#As you can see our Superdog has all moves defined in the base Dog class

파이썬에는 super ()도 있습니다. 파이썬의 구식과 새로운 스타일의 클래스 때문에 약간 까다 롭지 만 생성자에서 매우 일반적으로 사용됩니다.

class Foo(Bar):
    def __init__(self):
        super(Foo, self).__init__()
        self.baz = 5

나는 CLASS.__bases__이런 것을 사용하는 것이 좋습니다

class A:
   def __init__(self):
        print "I am Class %s"%self.__class__.__name__
        for parentClass in self.__class__.__bases__:
              print "   I am inherited from:",parentClass.__name__
              #parentClass.foo(self) <- call parents function with self as first param
class B(A):pass
class C(B):pass
a,b,c = A(),B(),C()

당신이 얻을 수있는 주장의 수를 모르고 자녀에게도 전달하려면 :

class Foo(bar)
    def baz(self, arg, *args, **kwargs):
        # ... Do your thing
        return super(Foo, self).baz(arg, *args, **kwargs)

(From : Python-super () 호출 후 선택적 kwarg를 사용해야하는 __init__을 재정의하는 가장 깨끗한 방법은 무엇입니까? )


파이썬에는 super ()도 있습니다.

서브 클래스 메소드에서 수퍼 클래스 메소드를 호출하는 방법에 대한 예

class Dog(object):
    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self,x):
        self.moves.append('walk')
        self.moves.append('run')
        self.moves.append(x)
    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super().moves_setup("hello world")
        self.moves.append('fly')
dog = Superdog('Freddy')
print (dog.name)
dog.moves_setup()
print (dog.get_moves()) 

이 예제는 위에서 설명한 것과 비슷하지만 super에는 인수가 전달되지 않은 차이점이 있습니다. 위의 코드는 python 3.4 버전에서 실행 가능합니다.


이 예에서 cafec_param은 기본 클래스 (부모 클래스)이고 abc는 자식 클래스입니다. abc는 기본 클래스에서 AWC 메소드를 호출합니다.

class cafec_param:

    def __init__(self,precip,pe,awc,nmonths):

        self.precip = precip
        self.pe = pe
        self.awc = awc
        self.nmonths = nmonths

    def AWC(self):

        if self.awc<254:
            Ss = self.awc
            Su = 0
            self.Ss=Ss
        else:
            Ss = 254; Su = self.awc-254
            self.Ss=Ss + Su   
        AWC = Ss + Su
        return self.Ss
         

    def test(self):
        return self.Ss
        #return self.Ss*4

class abc(cafec_param):
    def rr(self):
        return self.AWC()


ee=cafec_param('re',34,56,2)
dd=abc('re',34,56,2)
print(dd.rr())
print(ee.AWC())
print(ee.test())

산출

56

56

56


파이썬 2에서는 super ()로 운이 없었습니다. 이 SO 스레드에서 jimifiki의 대답을 파이썬에서 부모 메서드를 참조하는 방법을 사용 했습니까? . 그런 다음 사용 방법이 향상되었다고 생각합니다 (특히 클래스 이름이 긴 경우).

하나의 모듈에서 기본 클래스를 정의하십시오.

 # myA.py

class A():     
    def foo( self ):
        print "foo"

그런 다음 클래스를 다른 모듈로 가져옵니다 as parent.

# myB.py

from myA import A as parent

class B( parent ):
    def foo( self ):
        parent.foo( self )   # calls 'A.foo()'

class department:
    campus_name="attock"
    def printer(self):
        print(self.campus_name)

class CS_dept(department):
    def overr_CS(self):
        department.printer(self)
        print("i am child class1")

c=CS_dept()
c.overr_CS()

class a(object):
    def my_hello(self):
        print "hello ravi"

class b(a):
    def my_hello(self):
    super(b,self).my_hello()
    print "hi"

obj = b()
obj.my_hello()

이것은 더 추상적 인 방법입니다.

super(self.__class__,self).baz(arg)

참고 URL : https://stackoverflow.com/questions/805066/call-a-parent-classs-method-from-child-class-in-python



반응형