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 '__main__.FatBoss'>, <class '__main__.FatFather'>, <class 'object'>) =========== 下面按照 MRO 顺序执行super方法 ============= 胖子老板的类被调用啦! FatFather的init开始被调用 调用FatFather类的name是胖子老板 FatFather的init调用结束 胖子老板 的爱好是 打斗地主
위 결과(
다중 상속이 있으면 어떤 문제가 있나요?
2.4 super()를 사용한 다중 상속
뚱뚱한 상사의 딸을 위한 또 다른 클래스와 뚱뚱한 상사의 아내를 위한 클래스를 작성한다고 가정해 보겠습니다. 이때 딸은 두 개의 클래스(뚱뚱한 상사의 아내)를 상속받아야 합니다. 보스 클래스와 뚱뚱한 상사의 아내 클래스)를 동시에.
뚱뚱한 상사에게는 취미가 있기 때문에 뚱뚱한 상사의 아내는 일과 집안일을 해야 하기 때문에 그의 딸은 그 일을 동시에 도와야 합니다.
이때 딸이 이 두 부모 클래스의 메소드를 상속받아 사용해야 하는데 어떻게 작성해야 할까요?
구현 코드를 살펴보겠습니다.
# 胖子老板的父类 class FatFather(object): def __init__(self, name, *args, **kwargs): print() print("=============== 开始调用 FatFather ========================") print('FatFather的init开始被调用') self.name = name print('调用FatFather类的name是%s' % self.name) print('FatFather的init调用结束') print() print("=============== 结束调用 FatFather ========================") # 胖子老板类 继承 FatFather 类 class FatBoss(FatFather): def __init__(self, name, hobby, *args, **kwargs): print() print("=============== 开始调用 FatBoss ========================") print('胖子老板的类被调用啦!') #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('胖子老板的老婆类被调用啦!要学会干家务') #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('胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主') 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 '__main__.FatBossGril'>, <class '__main__.FatBoss'>, <class '__main__.FatBossWife'>, <class '__main__.FatFather'>, <class 'object'>) =========== 下面按照 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!