Skip to content

Latest commit

Β 

History

History
157 lines (122 loc) Β· 4.55 KB

File metadata and controls

157 lines (122 loc) Β· 4.55 KB

40. super 둜 λΆ€λͺ¨ 클래슀λ₯Ό μ΄ˆκΈ°ν™”ν•˜λΌ

1. λΆ€λͺ¨ 클래슀 μ΄ˆκΈ°ν™”

class MyBaseClass:
    def __init__(self, value):
        self.value = value
        
class MyChildClass(MyBaseClass):
    def __init__(self):
        MyBaseClass.__init__(self, 5)
  • μžμ‹ 클래슀 μƒμ„±μžμ—μ„œ λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό 직접 ν˜ΈμΆœν•¨
  • ν•΄λ‹Ή μ½”λ“œλŠ” 결함이 쑴재
    • 닀쀑 상속에 μ˜ν•΄ 영ν–₯을 λ°›λŠ” 경우 μƒμœ„ 클래슀의 μƒμ„±μžλ₯Ό 직접 ν˜ΈμΆœν•˜λ©΄ μ˜ˆμΈ‘ν•  수 μ—†λŠ” λ°©μ‹μœΌλ‘œ μž‘λ™ κ°€λŠ₯함
      • 닀이아λͺ¬λ“œ 상속
class TimesTwo:
    def __init__(self):
        self.value *= 2

class PlusFive:
    def __init__(self):
        self.value += 5

class OneWay(MyBaseClass, TimesTwo, PlusFive):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)

class AnotherWay(MyBaseClass, PlusFive, TimesTwo):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)

foo = OneWay(5)
print('첫 번째 λΆ€λͺ¨ 클래슀 μˆœμ„œμ— λ”°λ₯Έ 값은 (5 * 2) + 5 =', foo.value)

bar = AnotherWay(5)
print('두 번째 λΆ€λͺ¨ 클래슀 μˆœμ„œμ— λ”°λ₯Έ 값은', bar.value)

>>>
첫 번째 λΆ€λͺ¨ 클래슀 μˆœμ„œμ— λ”°λ₯Έ 값은 (5 * 2) + 5 = 15
두 번째 λΆ€λͺ¨ 클래슀 μˆœμ„œμ— λ”°λ₯Έ 값은 15
  • λΆ€λͺ¨ 클래슀의 상속 μˆœμ„œλ₯Ό λ‹€λ₯΄κ²Œ μ£Όμ—ˆμ„ λ•Œ κ²°κ³Ό
    • λ³€ν™” μ—†μŒ
    • 상속 μˆœμ„œμ™€ λΆ€λͺ¨ 클래슀 생성 μˆœμ„œκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŒ
class TimesSeven(MyBaseClass):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        self.value *= 7

class PlusNine(MyBaseClass):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        self.value += 9

class ThisWay(TimesSeven, PlusNine):
    def __init__(self, value):
        TimesSeven.__init__(self, value)
        PlusNine.__init__(self, value)

foo = ThisWay(5)
print('(5 * 7) + 9 = 44κ°€ λ‚˜μ™€μ•Ό ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ”', foo.value)

>>>
(5 * 7) + 9 = 44κ°€ λ‚˜μ™€μ•Ό ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ” 14
  • 닀이아λͺ¬λ“œ μƒμ†μ˜ 경우
    • TimeSeven μƒμ„±μžλΆ€ν„° μ‹€ν–‰ β†’ PlusNine μˆœμ„œλ‘œ μ‹€ν–‰λ˜μ–΄ (5 * 7) + 9 μˆœμ„œλ‘œ 계산될꺼라 μ˜ˆμƒ
    • κ·ΈλŸ¬λ‚˜ μ‹€μ œλ‘œλŠ” PlusNine μƒμ„±μž μ‹€ν–‰ μ‹œ value κ°€ 5둜 μ΄ˆκΈ°ν™”λ¨
    • κ·Έλž˜μ„œ 14κ°€ λ‚˜μ˜΄

2. super λ‚΄μž₯ ν•¨μˆ˜

  • super λ‚΄μž₯ ν•¨μˆ˜ 톡해 λΆ€λͺ¨ 클래슀 μƒμ„±μž 호좜
    • ν‘œμ€€ λ©”μ†Œλ“œ κ²°μ • μˆœμ„œ(Method Resolution OMRO) 적용됨
class TimesSevenCorrect(MyBaseClass):
    def __init__(self, value):
        super().__init__(value)
        self.value *= 7
        
class PlusNineCorrect(MyBaseClass):
    def __init__(self, value):
        super().__init__(value)
        self.value += 9

class GoodWay(TimesSevenCorrect, PlusNineCorrect):
    def __init__(self, value):
        super().__init__(value)

foo = GoodWay(5)
print('7 * (5 + 9) = 98이 λ‚˜μ™€μ•Ό ν•˜κ³  μ‹€μ œλ‘œλ„', foo.value)

>>>
7 * (5 + 9) = 98이 λ‚˜μ™€μ•Ό ν•˜κ³  μ‹€μ œλ‘œλ„ 98
  • 호좜 μˆœμ„œλŠ” ν΄λž˜μŠ€μ— λŒ€ν•œ MRO μ •μ˜λ₯Ό 따름
mro_str = '\n'.join(repr(cls) for cls in GoodWay.mro())
print(mro_str)

>>>
<class '__main__.GoodWay'>
<class '__main__.TimesSevenCorrect'>
<class '__main__.PlusNineCorrect'>
<class '__main__.MyBaseClass'>
<class 'object'>
  • 클래슀 계측 ꡬ쑰λ₯Ό 따라 root 클래슀의 μƒμ„±μžλ₯Ό 찾아듀어감

  • 그럼 κ²°κ΅­ μƒμ„±μž 호좜의 μ—­μˆœμœΌλ‘œ μž‘μ—… μˆ˜ν–‰

    • MyBaseClass β†’ PlusNineCorrect β†’ TImesSevenCorrect β†’ GoodWay
  • super ν•¨μˆ˜μ— λ„˜κΈΈ 수 μžˆλŠ” 2κ°€μ§€ νŒŒλΌλ―Έν„°

    • 1번째 νŒŒλΌλ―Έν„° : MRO λ·°λ₯Ό μ œκ³΅ν•  λΆ€λͺ¨ νƒ€μž…
    • 2번째 νŒŒλΌλ―Έν„° : 1 번째 νŒŒλΌλ―Έν„°λ‘œ μ§€μ •ν•œ νƒ€μž…μ˜ MRO 뷰에 μ ‘κ·Όν•  λ•Œ μ‚¬μš©ν•  μΈμŠ€ν„΄μŠ€
  • object μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•Œ 2개 νŒŒλΌλ―Έν„° μ§€μ •ν•  ν•„μš” μ—†μŒ

  • νŒŒλΌλ―Έν„° 없이 super λ₯Ό ν˜ΈμΆœν•΄λ„ νŒŒμ΄μ„  인터프리터가 μ•Œμ•„μ„œ μ±„μ›Œμ€Œ

class ExplicitTrisect(MyBaseClass):
    def __init__(self, value):
        super(ExplicitTrisect, self).__init__(value)
        self.value /= 3
class AutomaticTrisect(MyBaseClass):
    def __init__(self, value):
        super(__class__, self).__init__(value)
        self.value /= 3

class ImplicitTrisect(MyBaseClass):
    def __init__(self, value):
        super().__init__(value)
        self.value /= 3

assert ExplicitTrisect(9).value == 3
assert AutomaticTrisect(9).value == 3
assert ImplicitTrisect(9).value == 3