source

Python의 자녀 클래스에서 부모 클래스의 메서드를 호출하려면 어떻게 해야 합니까?

manycodes 2022. 11. 15. 21:33
반응형

Python의 자녀 클래스에서 부모 클래스의 메서드를 호출하려면 어떻게 해야 합니까?

Python에서 단순한 오브젝트 계층을 만들 때 파생 클래스에서 부모 클래스의 메서드를 호출할 수 있도록 하고 싶습니다.Perl 및 Java에서는 이에 super대한 키워드가 있습니다().Perl에서는 다음과 같이 할 수 있습니다.

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

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

Python에서는 부모 클래스의 이름을 자녀에서 명시적으로 지정해야 합니다.에서 저는 '아까보다'와 같은 .Foo::frotz()

이 행동은 깊은 위계를 만드는 것을 어렵게 하기 때문에 이것은 옳지 않은 것처럼 보인다.상속된 메서드를 정의한 클래스를 자녀들이 알아야 하는 경우 모든 종류의 정보 고통이 발생합니다.

이것이 비단뱀의 실제 한계인가요, 아니면 제가 이해하는 것의 차이인가요?

다음 기능을 사용합니다.

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

Python < 3 의 경우는, 명시적으로 새로운 스타일의 클래스 사용을 선택해, 다음을 사용할 필요가 있습니다.

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

Python은 슈퍼도 갖추고 있습니다.

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.whatever합니다.whateverAnyClass의 조상님들(예: 님의 조상님)AnyClass는 정의 또는 정의하지 않으며, 이는 다른 발생과 마찬가지로 "부모 메서드를 호출하는 자녀 클래스"에도 적용됩니다.

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

ifFooBar 、 , , 。Bar.__init__에서 할 수 Foo★★★★★★★★★★★★★★★★★를 통해super().__init__():

class Foo(Bar):

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

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

하지만

"자녀반에서 부모반의 메서드를 어떻게 부르나요?"

다음과 같은 의미도 있습니다.

"상속된 메서드를 뭐라고 합니까?"

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

예: python 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"

네, 이것은 매우 명백할 수도 있지만, 저는 사람들이 이것을 지적하지 않고 이 스레드를 떠나면 단지 파이썬의 상속된 메서드에 접근하기 위해 우스꽝스러운 후프를 통과해야 한다는 인상을 줄 수 있다고 생각합니다.특히 이 질문은 "Python에서 부모 클래스의 메서드에 액세스하는 방법"에 대한 검색에서 높게 평가되며, OP는 Python을 처음 접하는 사람의 관점에서 작성됩니다.

저는 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

Python에도 super()가 있습니다.Python의 구식 및 신식 클래스 때문에 약간 이상하지만, 컨스트럭터에서는 매우 일반적으로 사용되고 있습니다.

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__를 덮어쓰는 가장 깨끗한 방법?)

python에도 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()) 

이 예는 위에서 설명한 것과 유사합니다.하지만 슈퍼는 어떠한 주장도 전달받지 못한다는 한 가지 차이점이 있다.위의 코드는 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

Python 2에서는 super()의 운이 별로 없었습니다.나는 이 SO 스레드에 대한 jimifiki의 답변을 어떻게 python에서 부모 메서드를 참조할 것인가?그리고, 저만의 작은 트위스트를 추가했습니다만, 편리성의 향상이라고 생각합니다(특히 클래스명이 긴 경우는).

1개의 모듈에서 베이스 클래스를 정의합니다.

 # myA.py

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

그런 다음 클래스를 다른 모듈로 Import합니다.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.method어떤 경우라도요.상속이 비교적 깨끗한 경우 하위 클래스의 인스턴스에서도 작동합니다.

class Foo:
    def __init__(self, var):
        self.var = var
    
    def baz(self):
        return self.var

class Bar(Foo):
    pass

bar = Bar(1)
assert Foo.baz(bar) == 1
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/how-do-i-call-a-parent-classs-method-from-a-child-class-in-python

반응형