แ„‚ ๐Ÿ˜„ [7 ์ผ์ฐจ] : Flipped Units 36. ํด๋ž˜์Šค ์ƒ์†

๋ฐฑ๊ฑดยท2022๋…„ 1์›” 21์ผ
0

layout: single

title: Unit36 ํด๋ž˜์Šค ์ƒ์† ์‚ฌ์šฉํ•˜๊ธฐ

ํด๋ž˜์Šค ์ƒ์† ์‚ฌ์šฉํ•˜๊ธฐ

ํด๋ž˜์Šค ์ƒ์†(inheritance)

  • ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋Š”
    • ๋ถ€๋ชจ ํด๋ž˜์Šค(parent class)
    • ์Šˆํผ ํด๋ž˜์Šค(superclass)
  • ํŒŒ์ƒ ํด๋ž˜์Šค๋Š”
    • ์ž์‹ ํด๋ž˜์Šค(child class)
    • ์„œ๋ธŒ ํด๋ž˜์Šค(subclass)

๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๋Šฅ๋ ฅ์„ ๊ทธ๋Œ€๋กœ ํ™œ์šฉํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉ
๋™๋ฌผ์„ ์˜ˆ๋กœ ๋“ค๋ฉด ์ฒ™์ถ”๋™๋ฌผ์—์„œ ํฌ์œ ๋ฅ˜, ์กฐ๋ฅ˜, ํŒŒ์ถฉ๋ฅ˜ ๋“ฑ์„ ๋งŒ๋“œ๋Š” ์‹
๊ธฐ๋ฐ˜ํด๋ž˜์Šค = ์ฒ™์ถ”๋™๋ฌผ
ํŒŒ์ƒํด๋ž˜์Šค = ํฌ์œ ๋ฅ˜, ์กฐ๋ฅ˜

์‚ฌ๋žŒ ํด๋ž˜์Šค๋กœ ํ•™์ƒ ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ

class ๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„:
    ์ฝ”๋“œ
 
class ํŒŒ์ƒํด๋ž˜์Šค์ด๋ฆ„(๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„):
    ์ฝ”๋“œ
#์‚ฌ๋žŒ(์›์กฐ)์ค‘์— ํ•™์ƒ(์ƒ์†์ž)์ด ์žˆ๋Š” ๊ฒƒ
class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class Student(Person):
    def study(self):
        print('๊ณต๋ถ€ํ•˜๊ธฐ')
 
james = Student()
james.greeting()    # ์•ˆ๋…•ํ•˜์„ธ์š”.: ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค Person์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
james.study()       # ๊ณต๋ถ€ํ•˜๊ธฐ: ํŒŒ์ƒ ํด๋ž˜์Šค Student์— ์ถ”๊ฐ€ํ•œ study ๋ฉ”์„œ๋“œ.
์•ˆ๋…•ํ•˜์„ธ์š”.
๊ณต๋ถ€ํ•˜๊ธฐ

ํด๋ž˜์Šค ์ƒ์†์€ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€

# ์ƒ์†๊ด€๊ณ„ ํ™•์ธ
class Person:
    pass
class Student(Person):
    pass

issubclass(Student, Person)
True
# Student๊ฐ€ Person์˜ ํŒŒ์ƒ ํด๋ž˜์Šค์ด๋ฏ€๋กœ issubclass๋Š” True

์ƒ์† ๊ด€๊ณ„์™€ ํฌํ•จ ๊ด€๊ณ„ ์•Œ์•„๋ณด๊ธฐ

์–ด๋””์— ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

์ƒ์† ๊ด€๊ณ„ ( is-a ๊ด€๊ณ„ : Student is a Person)

class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class Student(Person):
    def study(self):
        print('๊ณต๋ถ€ํ•˜๊ธฐ')

ํฌํ•จ๊ด€๊ณ„ (has-a ๊ด€๊ณ„ : PersonList has a Person)

class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class PersonList:
    def __init__(self):
        self.person_list = []    # ๋ฆฌ์ŠคํŠธ ์†์„ฑ์— Person ์ธ์Šคํ„ด์Šค๋ฅผ ๋„ฃ์–ด์„œ ๊ด€๋ฆฌ
 
    def append_person(self, person):    # ๋ฆฌ์ŠคํŠธ ์†์„ฑ์— Person ์ธ์Šคํ„ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜
        self.person_list.append(person)

# ์ƒ์†์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์†์„ฑ์— ์ธ์Šคํ„ด์Šค๋ฅผ ๋„ฃ์–ด์„œ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ PersonList๊ฐ€ Person์„ ํฌํ•จ

๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†์„ฑ ์‚ฌ์šฉํ•˜๊ธฐ

๊ธฐ๋ฐ˜ํด๋ž˜์Šค์— ๋“ค์–ด์žˆ๋Š” ์ธ์Šคํ„ด์Šค ์†์„ฑ ์‚ฌ์šฉ

  • Peraon ํด๋ž˜์Šค์— hello ์†์„ฑ
  • Peraon ํด๋ž˜์Šค์˜ ์ƒ์†์„ ๋ฐ›์•„ Student ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ
  • Student๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ณ  hello ์†์„ฑ์— ์ ‘๊ทผ
class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '์•ˆ๋…•ํ•˜์„ธ์š”.'
 
class Student(Person):
    def __init__(self):
        print('Student __init__')
        self.school = 'ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ'
 
james = Student()
print(james.school)
print(james.hello)    # ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†์„ฑ์„ ์ถœ๋ ฅํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ
Student __init__
ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

/var/folders/nv/7gm32z8n6cz1dzxgymhz5lmh0000gn/T/ipykernel_17577/684535431.py in <module>
     11 james = Student()
     12 print(james.school)
---> 13 print(james.hello)    # ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†์„ฑ์„ ์ถœ๋ ฅํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ


AttributeError: 'Student' object has no attribute 'hello'

super()๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ

super()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ int ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ

  • super().๋ฉ”์„œ๋“œ()
class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '์•ˆ๋…•ํ•˜์„ธ์š”.'
 
class Student(Person):
    def __init__(self):
        print('Student __init__')
        super().__init__()                # super()๋กœ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ __init__ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
        self.school = 'ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ'
 
james = Student()
print(james.school)
print(james.hello)
Student __init__
Person __init__
ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ
์•ˆ๋…•ํ•˜์„ธ์š”.

๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ์†์„ฑ์„ ์ฐพ๋Š” ๊ณผ์ •

๊ธฐ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๊ฒฝ์šฐ

ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ init ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ๋žตํ•œ๋‹ค๋ฉด
๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ init์ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ
super()๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋ฉ

class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '์•ˆ๋…•ํ•˜์„ธ์š”.'
 
class Student(Person):
    pass
 
james = Student()
print(james.hello)
Person __init__
์•ˆ๋…•ํ•˜์„ธ์š”.

๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ์‚ฌ์šฉํ•˜๊ธฐ

ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ƒˆ๋กœ ์ •์˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ

# Person์˜ greeting ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ์ƒํƒœ์—์„œ Student์—๋„ greeting ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ญ
class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class Student(Person):
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”. ์ €๋Š” ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ ํ•™์ƒ์ž…๋‹ˆ๋‹ค.')
 
james = Student()
james.greeting()
์•ˆ๋…•ํ•˜์„ธ์š”. ์ €๋Š” ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ ํ•™์ƒ์ž…๋‹ˆ๋‹ค.

์˜ค๋ฒ„๋ผ์ด๋”ฉ ์‚ฌ์šฉ ์ด์œ 

  • ํ”„๋กœ๊ทธ๋žจ์—์„œ ์–ด๋–ค ๊ธฐ๋Šฅ์ด ๊ฐ™์€ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์œผ๋กœ ๊ณ„์† ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•  ๋•Œ
class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class Student(Person):
    def greeting(self):
        super().greeting()    # ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜์—ฌ ์ค‘๋ณต์„ ์ค„์ž„
        print('์ €๋Š” ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ ํ•™์ƒ์ž…๋‹ˆ๋‹ค.')
 
james = Student()
james.greeting()
์•ˆ๋…•ํ•˜์„ธ์š”.
์ €๋Š” ํŒŒ์ด์ฌ ์ฝ”๋”ฉ ๋„์žฅ ํ•™์ƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์ค‘ ์ƒ์† ์‚ฌ์šฉํ•˜๊ธฐ

class ๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„1:
    ์ฝ”๋“œ
 
class ๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„2:
    ์ฝ”๋“œ
 
class ํŒŒ์ƒํด๋ž˜์Šค์ด๋ฆ„(๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„1, ๊ธฐ๋ฐ˜ํด๋ž˜์Šค์ด๋ฆ„2):
    ์ฝ”๋“œ
class Person:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”.')
 
class University:
    def manage_credit(self):
        print('ํ•™์  ๊ด€๋ฆฌ')     # ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค Person๊ณผ University
 
class Undergraduate(Person, University):
    def study(self):
        print('๊ณต๋ถ€ํ•˜๊ธฐ')   
                # ํŒŒ์ƒ ํด๋ž˜์Šค Undergraduate๋ฅผ ๋งŒ๋“ค ๋•Œ 
                # class Undergraduate(Person, University):์™€ 
                # ๊ฐ™์ด ๊ด„ํ˜ธ ์•ˆ์— Person๊ณผ University๋ฅผ 
                # ์ฝค๋งˆ๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ๋„ฃ์Œ 
                # ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‘ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ƒ์†

james = Undergraduate()
james.greeting()         # ์•ˆ๋…•ํ•˜์„ธ์š”. : ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค Person์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
james.manage_credit()    # ํ•™์  ๊ด€๋ฆฌ  : ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค University์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
james.study()            # ๊ณต๋ถ€ํ•˜๊ธฐ   : ํŒŒ์ƒ ํด๋ž˜์Šค Undergraduate์— ์ถ”๊ฐ€ํ•œ study ๋ฉ”์„œ๋“œ
์•ˆ๋…•ํ•˜์„ธ์š”.
ํ•™์  ๊ด€๋ฆฌ
๊ณต๋ถ€ํ•˜๊ธฐ
# ๋‹ค์Œ๊ณผ ๊ฐ™์ด Undergraduate ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋กœ 
# Person์˜ greeting๊ณผ University์˜ manage_credit์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ

james = Undergraduate()
james.greeting()         # ์•ˆ๋…•ํ•˜์„ธ์š”. : ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค Person์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
james.manage_credit()    # ํ•™์  ๊ด€๋ฆฌ  : ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค University์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
james.study()            # ๊ณต๋ถ€ํ•˜๊ธฐ   : ํŒŒ์ƒ ํด๋ž˜์Šค Undergraduate์— ์ถ”๊ฐ€ํ•œ study ๋ฉ”์„œ๋“œ
์•ˆ๋…•ํ•˜์„ธ์š”.
ํ•™์  ๊ด€๋ฆฌ
๊ณต๋ถ€ํ•˜๊ธฐ

Person, University, Undergraduate ํด๋ž˜์Šค์˜ ๊ด€๊ณ„

๋‹ค์ด์•„๋ชฌ๋“œ ์ƒ์†

class A:
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”. A์ž…๋‹ˆ๋‹ค.')
 
class B(A):
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”. B์ž…๋‹ˆ๋‹ค.')
 
class C(A):
    def greeting(self):
        print('์•ˆ๋…•ํ•˜์„ธ์š”. C์ž…๋‹ˆ๋‹ค.')
 
class D(B, C):
    pass
 
x = D()
x.greeting()    # ์•ˆ๋…•ํ•˜์„ธ์š”. B์ž…๋‹ˆ๋‹ค.
์•ˆ๋…•ํ•˜์„ธ์š”. B์ž…๋‹ˆ๋‹ค.

๋ฉ”์†Œ๋“œ ํƒ์ƒ‰ ์ˆœ์„œ ํ™•์ธ

  • ๋ฉ”์„œ๋“œ ํƒ์ƒ‰ ์ˆœ์„œ(Method Resolution Order, MRO)๋ฅผ ๋”ฐ๋ฆ„
  • ํด๋ž˜์Šค D์— ๋ฉ”์„œ๋“œ mro๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ๋ฉ”์„œ๋“œ ํƒ์ƒ‰ ์ˆœ์„œ๊ฐ€ ๋‚˜์˜ด.
D.mro()
[__main__.D, __main__.B, __main__.C, __main__.A, object]

D์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ˆœ์„œ๋Š”

  • ์ž๊ธฐ ์ž์‹  D,
  • ๊ทธ ๋‹ค์Œ์ด B์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ D๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ณ  greeting์„ ํ˜ธ์ถœํ•˜๋ฉด B์˜ greeting์ด ํ˜ธ์ถœ
x = D()
x.greeting()    # ์•ˆ๋…•ํ•˜์„ธ์š”. B์ž…๋‹ˆ๋‹ค.
์•ˆ๋…•ํ•˜์„ธ์š”. B์ž…๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ์€ ๋‹ค์ค‘ ์ƒ์†์„ ํ•œ๋‹ค๋ฉด class D(B, C):์˜ ํด๋ž˜์Šค ๋ชฉ๋ก ์ค‘ ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ ์ˆœ์„œ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด B๊ฐ€ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ƒ์† ๊ด€๊ณ„๊ฐ€ ๋ณต์žกํ•˜๊ฒŒ ์–ฝํ˜€ ์žˆ๋‹ค๋ฉด MRO๋ฅผ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌ

์ถ”์ƒ ํด๋ž˜์Šค ์‚ฌ์šฉํ•˜๊ธฐ

์ถ”์ƒ ํด๋ž˜์Šค(abstract class)๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต

  • ๋ฉ”์„œ๋“œ์˜ ๋ชฉ๋ก๋งŒ ๊ฐ€์ง„ ํด๋ž˜์Šค์ด๋ฉฐ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„œ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
  • ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด import๋กœ abc ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค( abc๋Š” abstract base class์˜ ์•ฝ์ž)
  • ํด๋ž˜์Šค์˜ ( )(๊ด„ํ˜ธ) ์•ˆ์— metaclass=ABCMeta๋ฅผ ์ง€์ •
  • ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ„์— @abstractmethod๋ฅผ ๋ถ™์—ฌ์„œ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ์ง€์ •
from abc import *
 
class ์ถ”์ƒํด๋ž˜์Šค์ด๋ฆ„(metaclass=ABCMeta):
    @abstractmethod
    def ๋ฉ”์„œ๋“œ์ด๋ฆ„(self):
        ์ฝ”๋“œ
  • from abc import *๋กœ abc ๋ชจ๋“ˆ์˜ ๋ชจ๋“  ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ ๊ฐ€์ ธ์˜ด.
  • ๋งŒ์•ฝ import abc๋กœ ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์™”๋‹ค๋ฉด abc.ABCMeta, @abc.abstractmethod๋กœ ์‚ฌ์šฉ
# ํ•™์ƒ ์ถ”์ƒ ํด๋ž˜์Šค StudentBase๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ํ•™์ƒ ํด๋ž˜์Šค Student
from abc import *
 
class StudentBase(metaclass=ABCMeta):
    @abstractmethod
    def study(self):
        pass
 
    @abstractmethod
    def go_to_school(self):
        pass
 
class Student(StudentBase):
    def study(self):
        print('๊ณต๋ถ€ํ•˜๊ธฐ')
 
james = Student()
james.study()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/var/folders/nv/7gm32z8n6cz1dzxgymhz5lmh0000gn/T/ipykernel_17577/186541337.py in <module>
     15         print('๊ณต๋ถ€ํ•˜๊ธฐ')
     16 
---> 17 james = Student()
     18 james.study()


TypeError: Can't instantiate abstract class Student with abstract methods go_to_school

์ถ”์ƒ ํด๋ž˜์Šค StudentBase์—์„œ๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ study์™€ go_to_school์„ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ StudentBase๋ฅผ ์ƒ์†๋ฐ›์€ Student์—์„œ๋Š” study ๋ฉ”์„œ๋“œ๋งŒ ๊ตฌํ˜„ํ•˜๊ณ , go_to_school ๋ฉ”์„œ๋“œ๋Š” ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ

from abc import *
 
class StudentBase(metaclass=ABCMeta):
    @abstractmethod
    def study(self):
        pass
 
    @abstractmethod
    def go_to_school(self):
        pass
 
class Student(StudentBase):
    def study(self):
        print('๊ณต๋ถ€ํ•˜๊ธฐ')
 
    def go_to_school(self):
        print('ํ•™๊ต๊ฐ€๊ธฐ')
 
james = Student()
james.study()
james.go_to_school()
๊ณต๋ถ€ํ•˜๊ธฐ
ํ•™๊ต๊ฐ€๊ธฐ

์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ๋นˆ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“œ๋Š” ์ด์œ 

  • ์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค ์ˆ˜๊ฐ€ ์—†๋‹ค๋Š” ์ 
  • ์ถ”์ƒ ํด๋ž˜์Šค StudentBase๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ
james = StudentBase()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/var/folders/nv/7gm32z8n6cz1dzxgymhz5lmh0000gn/T/ipykernel_17577/1043146601.py in <module>
----> 1 james = StudentBase()


TypeError: Can't instantiate abstract class StudentBase with abstract methods go_to_school, study

์ง€๊ธˆ๊นŒ์ง€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ pass๋งŒ ๋„ฃ์–ด์„œ ๋นˆ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†์œผ๋‹ˆ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋„ ํ˜ธ์ถœํ•  ์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ

    @abstractmethod
    def study(self):
        pass    # ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ผ์ด ์—†์œผ๋ฏ€๋กœ ๋นˆ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“ฆ
 
    @abstractmethod
    def go_to_school(self):
        pass    # ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ผ์ด ์—†์œผ๋ฏ€๋กœ ๋นˆ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“ฆ

์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค ๋•Œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ ์˜ค๋กœ์ง€ ์ƒ์†์—๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ •ํ•ด ์ค„ ๋•Œ ์‚ฌ์šฉ

๋ฌธ์ œํ’€๊ธฐ

ํ€ด์ฆˆ

์—ฐ์Šต๋ฌธ์ œ: ๋ฆฌ์ŠคํŠธ์— ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•˜๊ธฐ

์‹ฌ์‚ฌ๋ฌธ์ œ: ๋‹ค์ค‘ ์ƒ์† ์‚ฌ์šฉํ•˜๊ธฐ

์ด์ •๋ฆฌ

ํด๋ž˜์Šค(Class)๋ž€ ๋ฌด์—‡์ธ๊ฐ€

  • ์ž๋ฃŒํ˜•์„ ์œ„ํ•œ ์ผ์ข…์˜ ํ…œํ”Œ๋ฆฟ
  • ์ฐธ๊ณ 
    • ์ž๋ฃŒํ˜• (type)
print(type("string"))
print(type(1))
<class 'str'>
<class 'int'>
class TestClass:
  pass

์ธ์Šคํ„ด์Šค (Instantiation)

  • ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ๋‚˜๋ฉด ๊ทธ๊ฑธ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•
  • ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด ์ธ์Šคํ„ด์Šค(instance)๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ๋จ
  • ์ž„์‹œ๋กœ ์–ด๋–ค ํ…œํ”Œ๋ฆฟ์„ ๋ถˆ๋Ÿฌ์™€์„œ ๊ทธ๊ฑธ ๋‹ค๋ฅธ ์ด๋ฆ„์˜ ๊ฐ์ฒด๋กœ ์ €์žฅ
test_instance = TestClass()
  • ํด๋ž˜์Šค ์ด๋ฆ„์— ๊ด„ํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ๊ฑธ ๋ณ€์ˆ˜ @@@_instance์— ํ• ๋‹น
  • ์ˆ˜๋งŽ์€ ์ธ์Šคํ„ด์Šค๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ
test_instance1 = TestClass()
test_instance2 = TestClass()
test_instance3 = TestClass()

๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (Object-Oriented Programming)

  • ํด๋ž˜์Šค, ์ธ์Šคํ„ด์Šค๋Š” ๊ฐ์ฒด(object)
  • ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ํŒจํ„ด์„ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)
  • ์ธ์Šคํ„ด์Šค๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค๋Š” ๊ฑด ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ ธ์™€ ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค๋Š” ๊ฒƒ
  • type() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ๊ทธ ๋ฐ˜๋Œ€
    • ๊ฐ์ฒด์˜ type์„ ํ™•์ธํ•ด๋ณด๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€๋ฅผ ํ™•์ธ
print(type(test_instance))
# <class '__main__.TestClass'>
<class '__main__.TestClass'>
  • main์€ โ€œํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํŒŒ์ผโ€์„ ์˜๋ฏธ

ํด๋ž˜์Šค ๋ณ€์ˆ˜ (Class Variables)

  • ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ทธ ์•ˆ์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋ฉด ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์—์„œ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ
  • ์ •์˜๋œ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋Š” object.variable ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ก์„ธ์Šค
class Musician:
  title = "Rockstar"

๊ฐ๊ฐ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ํ˜ธ์ถœํ•ด๋„ ๊ฐ ์ธ์Šคํ„ด์Šค ์•ˆ์— ์žˆ๋Š” title ๋ณ€์ˆ˜๋Š” ๋˜‘๊ฐ™์Œ

drummer = Musician()
guitarist = Musician()
print(drummer.title)
print(guitarist .title)
Rockstar
Rockstar

๋ฉ”์„œ๋“œ (Methods)

  • ๋ฉ”์„œ๋“œ๋Š” ํด๋ž˜์Šค ์•ˆ์—์„œ ์ •์˜๋œ ํ•จ์ˆ˜
  • ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ํ•ญ์ƒ self๋กœ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค
class Musician:
    title = "Rockstar"
    def explanation(self):
        print("I am a {}!".format(self.title))
drummer = Musician()
drummer.explanation()
#I am a Rockstar!
I am a Rockstar!
  • ํ•จ์ˆ˜ ์•ˆ์—์„œ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” self.title๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ด
class Circle():
    pi = 3.14
  
    def area(self, radius):
        return self.pi * radius ** 2
  
circle = Circle()

pizza_area = circle.area(6)
table_area = circle.area(18)

์ƒ์„ฑ์ž (Constructor)

  • ํด๋ž˜์Šค๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž๋™์œผ๋กœ ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ๊ฐ’์„ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ƒ์„ฑ์ž(Constructor)๋ผ๋Š” ๊ฑธ ์ •์˜
  • ๋ฉ”์„œ๋“œ ์ •์˜ํ•  ๋•Œ์™€ ๋˜‘๊ฐ™๊ธด ํ•œ๋ฐ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์œผ๋กœ init์„ ์‚ฌ์šฉ
class Shouter:
    def __init__(self):
        print("HELLO?!")
shout = Shouter()
HELLO?!
  • Shouter๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ๊ฐ์ฒด๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๋ฌธ์ž์—ด์ด ์ฆ‰์‹œ ์ถœ๋ ฅ
class Circle:
    pi = 3.14
    def __init__(self, radius):
        print("New circle with radius: {}".format(radius))
table = Circle(18)
New circle with radius: 18

Circle์ด๋ผ๋Š” ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž init์„ ์ž˜ ์‚ดํŽด๋ณด๋ฉด self ๋ง๊ณ ๋„ radius๋ผ๋Š” ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ด„ํ˜ธ ์•ˆ์— ์ธ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•จ

์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ (Instance Variables)

  • ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ณ„ํ•ด์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ, ์ฆ‰ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๋ณด์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
  • ๊ฐ ๊ฐ์ฒด๊ฐ€ ๋ณด์œ ํ•œ ๋ฐ์ดํ„ฐ์ธ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๊ฒŒ ์•„๋‹˜
# ์ผ๋‹จ ํด๋ž˜์Šค ์ •์˜ ๋‘๊ฐœ์˜ ์ธ์Šคํ„ด์Šค ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
class FakeDict:
    pass
fake_dict1 = FakeDict()
fake_dict2 = FakeDict()
# ๊ฐ ๊ฐ์ฒด์— fake_key๋ผ๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด
fake_dict1.fake_key = "This works!"
fake_dict2.fake_key = "This too!"
# ๋ณ„๋„๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ
working_string = "{} {}".format(fake_dict1.fake_key, fake_dict2.fake_key)
print(working_string)
This works! This too!

์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์˜ ํ™œ์šฉ, self

  • ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž‘๋™ํ•˜๋Š” ์ƒ์„ฑ์ž(constructor)๋ฅผ ํ™œ์šฉํ•ด์„œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋ฉด ๋„ˆ๋ฌด๋‚˜ ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž„
  • ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์• ์ดˆ์— ์ด๋ฆ„์„ ๋„ฃ์–ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ์ธ์Šคํ„ด์Šค์˜ name์—์„œ ๊ทธ ์ด๋ฆ„์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋จ
  • ํ™œ์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑ
  • ํด๋ž˜์Šค ๋ณ€์ˆ˜์™€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋‘ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
class AutoEmail:
    def __init__(self, name):
        self.name = name

mail_to_park = AutoEmail("PARK")
mail_to_kim = AutoEmail("KIM")

print(mail_to_park.name)
# "PARK"

print(mail_to_kim.name)
# "KIM"
PARK
KIM

์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ด๋ฆ„์„ ๋„ฃ์–ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ์ธ์Šคํ„ด์Šค์˜ name์—์„œ ๊ทธ ์ด๋ฆ„์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋จ

class AutoEmail:
    intro = "์•ˆ๋…•ํ•˜์„ธ์š”"

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

    def say_hello(self):
        return "{intro} {name} ๋‹˜".format(intro=self.intro, name=self.name)

mail_to_park = AutoEmail("PARK")
mail_to_kim = AutoEmail("KIM")

print(mail_to_park.say_hello())
# "์•ˆ๋…•ํ•˜์„ธ์š” PARK ๋‹˜"

print(mail_to_kim.say_hello())
# "์•ˆ๋…•ํ•˜์„ธ์š” KIM ๋‹˜"

ํด๋ž˜์Šค ๋ณ€์ˆ˜์™€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ๋ชจ๋‘ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

profile
๋งˆ์ผ€ํŒ…์„ ์œ„ํ•œ ์ธ๊ณต์ง€๋Šฅ ์„ค๊ณ„์™€ ์Šคํƒ€ํŠธ์—… Log

0๊ฐœ์˜ ๋Œ“๊ธ€