> 백엔드 개발 > 파이썬 튜토리얼 > Python의 super() 메소드에 대한 자세한 설명

Python의 super() 메소드에 대한 자세한 설명

爱喝马黛茶的安东尼
풀어 주다: 2019-08-22 17:27:13
앞으로
2410명이 탐색했습니다.

Python의 super() 메소드에 대한 자세한 설명

1. 상위 클래스의 메소드만 호출

요구 사항: 클래스를 작성하고 상속할 하위 클래스를 작성하고, 하위 클래스를 사용하여 상위 클래스의 메소드 1을 호출합니다.

방법 1을 사용하여 인쇄하세요: 뚱뚱한 상사님, 와서 빈랑을 포장하세요.

그런 다음 먼저 Fat Boss의 상위 클래스를 작성하고 실행합니다.

class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('FatFather的name是%s' % self.name)
        print('FatFather的init调用结束')
def main():
    ff = FatFather("胖子老板的父亲")
로그인 후 복사

이 Fat Boss 상위 클래스의 생성자 init를 다음과 같이 실행합니다.

if __name__ == "__main__":
    main()
FatFather的init开始被调用
FatFather的name是胖子老板的父亲
FatFather的init调用结束
로그인 후 복사

좋아, 그런 다음 Fat Boss 클래스인 하위 클래스를 작성해 상속합니다. 위의 수업.

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        FatFather.__init__(self, name)  # 直接调用父类的构造方法
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")
로그인 후 복사

위 코드에서는 FatFather.init(self,name)을 사용하여 상위 클래스의 메서드를 직접 호출했습니다.

실행 결과는 다음과 같습니다.

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
로그인 후 복사
로그인 후 복사

2. super() 메소드의 기본 개념

FatFather.init(self,name) 메소드를 직접 사용하는 것 외에 super() 메소드를 사용할 수도 있습니다. 그것을 부르려고.

그런 다음 먼저 super() 메서드의 사용법을 이해하려면 super() 메서드에 대한 설명과 구문을 읽어야 합니다.

2.1 설명

super() 함수는 상위 클래스(슈퍼 클래스)를 호출하는 데 사용되는 메소드입니다.

super는 다중 상속 문제를 해결하는 데 사용됩니다. 단일 상속을 사용하는 경우 클래스 이름으로 부모 클래스 메서드를 직접 호출하는 것은 문제가 되지 않습니다. 그러나 다중 상속을 사용하면 검색 순서(MRO)와 반복 호출이 발생합니다. (다이아몬드 상속) 및 기타 문제.

MRO는 클래스의 메서드를 구문 분석하는 시퀀스 테이블입니다. 실제로는 상위 클래스 메서드를 상속할 때의 시퀀스 테이블입니다.

관련 권장사항: "Python Video Tutorial"

2.2 구문

다음은 super() 메소드의 구문입니다:

super(type[, object-or-type])
로그인 후 복사

Parameters

type -- class

object-or-type - - class, 일반적으로 self

Python3.x와 Python2.x의 한 가지 차이점은 다음과 같습니다. Python 3에서는 super(Class, self).xxx 대신 super().xxx를 직접 사용할 수 있습니다.

Python3.x 예:

class A:
    pass
class B(A):
    def add(self, x):
        super().add(x)
로그인 후 복사

Python2.x 예:

class A(object):   # Python2.x 记得继承 object
    pass
class B(A):
    def add(self, x):
        super(B, self).add(x)
로그인 후 복사

2.3 super()를 사용한 단일 상속

super() 메서드를 사용하여 지금 막 부모 클래스를 상속하는 뚱뚱한 보스의 init 생성 메서드를 다시 작성하세요

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")
로그인 후 복사

에서 super 메서드를 사용할 때 위의 경우 단일 상속이므로 직접 사용할 수 있습니다.

작업은 다음과 같습니다.

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
로그인 후 복사
로그인 후 복사

그렇다면 왜 단일 상속을 직접 사용할 수 있다고 할까요? super() 메서드에 다중 상속이 있는 경우 MRO(상위 클래스 메서드 상속 시 시퀀스 테이블) 호출 순서 문제가 발생하기 때문입니다.

아래에서 인쇄하여 단일 상속의 MRO 시퀀스(FatBoss.mro)를 볼 수 있습니다.

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    print("打印FatBoss类的MRO")
    print(FatBoss.__mro__)
    print()
    print("=========== 下面按照 MRO 顺序执行super方法 =============")
    fatboss = FatBoss("胖子老板", "打斗地主")
로그인 후 복사

위 코드는 FatBoss.mro를 사용하여 Python 파서의 C3 알고리즘으로 계산된 FatBoss 클래스의 상속 호출 순서를 인쇄합니다.

다음과 같이 실행하세요:

if __name__ == "__main__":
    main()
打印FatBoss类的MRO
(<class &#39;__main__.FatBoss&#39;>, <class &#39;__main__.FatFather&#39;>, <class &#39;object&#39;>)
=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
로그인 후 복사

위 결과(, , )에서 우리는 FatBoss의 ( ) 메소드는 FatFather인 상위 클래스를 직접 호출하므로 단일 상속은 문제가 되지 않습니다.

다중 상속이 있으면 어떤 문제가 있나요?

2.4 super()를 사용한 다중 상속

뚱뚱한 상사의 딸을 위한 또 다른 클래스와 뚱뚱한 상사의 아내를 위한 클래스를 작성한다고 가정해 보겠습니다. 이때 딸은 두 개의 클래스(뚱뚱한 상사의 아내)를 상속받아야 합니다. 보스 클래스와 뚱뚱한 상사의 아내 클래스)를 동시에.

뚱뚱한 상사에게는 취미가 있기 때문에 뚱뚱한 상사의 아내는 일과 집안일을 해야 하기 때문에 그의 딸은 그 일을 동시에 도와야 합니다.

이때 딸이 이 두 부모 클래스의 메소드를 상속받아 사용해야 하는데 어떻게 작성해야 할까요?

구현 코드를 살펴보겠습니다.

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name, *args, **kwargs):
        print()
        print("=============== 开始调用 FatFather  ========================")
        print(&#39;FatFather的init开始被调用&#39;)
        self.name = name
        print(&#39;调用FatFather类的name是%s&#39; % self.name)
        print(&#39;FatFather的init调用结束&#39;)
        print()
        print("=============== 结束调用 FatFather  ========================")
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBoss  ========================")
        print(&#39;胖子老板的类被调用啦!&#39;)
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 的爱好是 %s" % (name, hobby))
        print()
        print("=============== 结束调用 FatBoss  ========================")
# 胖子老板的老婆类 继承 FatFather类
class FatBossWife(FatFather):
    def __init__(self, name, housework, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBossWife  ========================")
        print(&#39;胖子老板的老婆类被调用啦!要学会干家务&#39;)
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 需要干的家务是 %s" % (name, housework))
        print()
        print("=============== 结束调用 FatBossWife  ========================")
# 胖子老板的女儿类 继承 FatBoss FatBossWife类
class FatBossGril(FatBoss, FatBossWife):
    def __init__(self, name, hobby, housework):
        print(&#39;胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主&#39;)
        super().__init__(name, hobby, housework)
def main():
    print("打印FatBossGril类的MRO")
    print(FatBossGril.__mro__)
    print()
    print("=========== 下面按照 MRO 顺序执行super方法 =============")
    gril = FatBossGril("胖子老板", "打斗地主", "拖地")
로그인 후 복사

실행 결과는 다음과 같습니다.

if __name__ == "__main__":
    main()
打印FatBossGril类的MRO
(<class &#39;__main__.FatBossGril&#39;>, <class &#39;__main__.FatBoss&#39;>, <class &#39;__main__.FatBossWife&#39;>, 
<class &#39;__main__.FatFather&#39;>, <class &#39;object&#39;>)
=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主
=============== 开始调用 FatBoss  ========================
胖子老板的类被调用啦!
=============== 开始调用 FatBossWife  ========================
胖子老板的老婆类被调用啦!要学会干家务
=============== 开始调用 FatFather  ========================
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
=============== 结束调用 FatFather  ========================
胖子老板 需要干的家务是 拖地
=============== 结束调用 FatBossWife  ========================
胖子老板 的爱好是 打斗地主
=============== 结束调用 FatBoss  ========================
로그인 후 복사

위 실행 결과에서 각 클래스 호출의 시작과 끝을 특별히 인쇄해 놓은 것을 보실 수 있습니다.

각 클래스의 시작 호출은 MRO 순서에 따라 시작되어 하나씩 종료됩니다.

또한 서로 다른 상위 클래스를 상속해야 하기 때문에 매개변수가 반드시 확실하지는 않습니다.

따라서 모든 상위 클래스는 변수 매개변수 *args 및 **kwargs를 추가해야 합니다. 그렇지 않으면 매개변수가 일치하지 않으면 오류가 보고됩니다.

3. Notes

·Super().init는 기본적으로 단일 상속의 클래스 name.init와 사용법에 차이가 없습니다.

·다중 상속에는 차이가 있습니다. 슈퍼 메소드는 각 상위 클래스 메소드가 한 번만 실행되도록 할 수 있지만 클래스 이름을 사용하는 메소드는 메소드가 여러 번 실행되도록 시도할 수 있습니다. 결과를 보기 위해 코드를 작성합니다.

·super 메소드를 사용할 때 상위 클래스에 전달되는 매개변수는 Python의 super 알고리즘으로 인해 전달되어야 하며, 그렇지 않으면 오류가 보고됩니다.

·단일 상속에서 슈퍼 메소드를 사용하는 경우 모든 매개변수를 전달할 수 없습니다. 상위 클래스 메소드에 필요한 매개변수만 전달할 수 있습니다. 그렇지 않으면 오류가 보고됩니다.

·다중 상속을 사용할 경우 클래스 name.init 메소드를 사용할 때와 비교하여 모든 상위 클래스를 한 번 작성해야 하지만 super 메소드를 사용하면 한 문장만 작성하면 모든 상위 클래스 메소드를 모두 실행할 수 있습니다. . 다중 상속이 모든 매개변수를 전달해야 하는 이유 중 하나이기도 합니다.

4. 연습

다음 코드의 결과는 무엇입니까? 답을 말하고 설명해 보세요.

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print(Parent.x, Child1.x, Child2.x)
1 1 1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
1 2 1
로그인 후 복사

참고: Child1은 이미 자신의 x

Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
3 2 3
로그인 후 복사
를 가지고 있습니다.

위 내용은 Python의 super() 메소드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:jianshu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿