클래스란?

  • 클래스는 프로그램 작성에 꼭 필요한 요소는 아니지만, 타인의 코드를 이해하거나 n개 함수 구현을 원할때, 불필요한 반복적 코드 작성 등에 유용함

  • 클래스란 똑같은 무엇인가를 계속 만들어 낼 수도 있는 설계도면이고 객체란 클래스로 만든 피조물을 뜻한다. (ref_점프투파이썬(박응용): https://wikidocs.net/28#_1)

  • Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state. Class instances can also have methods (defined by its class) for modifying its state.(ref: https://docs.python.org/3/tutorial/classes.html)

  • 직접적 설명

    • 복제를 위한 확장가능한 프로그램 코드의 유닛

STEP

(1) 개념의 인지

(2) 복사하고 싶은 속성을 추림

(3) 복사가능한 어떤 틀을 만듦 (=클래스를 정의)

(4) 틀에서 인스턴스를 만든다 (=클래스에서 인스턴스를 만든다)


일단! 개념 설명

class STUDY:
    pass

a=STUDY()

여기서 a는 객체(object)이며, 동시에 class의 인스턴스(instance)이다.

class 안에 함수가 구현된다면? 메서드(Method)라 칭한다

클래스 인스턴스
과자틀 과자
공장 공장에서 나온 생산품
설계도 설계도 바탕으로 소프트웨어 세계에 구현된 실체
프로그램 프로세스

Create class

from PIL import Image
class TODOLIST(): ## TODOLIST 라는 이름을 가진 클래스 선언
    title='To Do List' ## class 안에서 정의된 변수 1
    img=Image.open('img.jpg').resize((250,250)) ## class 안에서 정의된 변수 2
    Q="Are you done?" ## class 안에서 정의된 변수 3
    A="Yeah!!" ## class 안에서 정의된 변수 4
    def nothing(self): ## class 안에서 정의된 함수
        print(self.title)
        display(self.img)
        print(self.Q,self.A)

파이썬 메서드의 첫 번째 매개변수 이름은 관례적으로 self를 사용한다. 객체를 호출할 때 호출한 객체 자신이 전달되기 때문에 self를 사용한 것이다. 물론 self말고 다른 이름을 사용해도 상관없다.

ref(점프투파이썬_박응용): https://wikidocs.net/28#_1

규칙1: 클래스내에서 함수를 선언하면 반드시 첫번째 인자는 self를 넣어야 한다. --> self가 뭘까?

규칙2: 클래스 내에서 정의한 변수 (예를들면 title, img, Q, A)를 사용하려면

  • self 이용하는 법
    • self.title, self.img, self.Q, self.A
  • class 이름을 그대로 쓰는 방법
    • TODOLIST.title, TODOLIST.img, TODOLIST.Q, TODOLIST.A

Create instance

Step1: 클래스에서 인스턴스를 만듦

Step2: 인스턴스에서 nothing 함수를 사용

클래스에서 인스턴스를 찍어내는 방법

  • 함수사용법과 비슷
  • 클래스 이름을 쓰고 콘텐츠를 구체화시키는 과정에서 필요한 입력1, 입력2를 ()에 넣는다.
  • TODOLIST의 경우는 따로 입력이 없으므로, 그냥 TODOLIST하고 입력을 비워둔다. 즉 TODOLIST()로 생성
todo1=TODOLIST() ### 첫번째 인스턴스 생성
todo1?
Type:        TODOLIST
String form: <__main__.TODOLIST object at 0x7f3c8130d9a0>
Docstring:   <no docstring>
  • 왜 타입을 class명으로 받을까? 아래 설명 예정

todo1.하고 탭을 눌러보자.

  • 주황색: A, Q, img, title
  • 파란식: nothing <-- 함수
    • 함수의 입력: self
    • 함수의 기능: print, display, print
todo1.nothing()
To Do List
Are you done? Yeah!!

class의 다양한 사용!

성능1: 인스턴스에서 .을 찍고 접근할 수 있는 여러 자료들을 정의할 수 있다.

todo1.title
'To Do List'

성능2:인스턴스에서 .을 찍고 쓸 수 있는 자체적인 함수(=method라고 함)를 정의할 수 있다.

todo1.nothing()
To Do List
Are you done? Yeah!!

성능3: 내용을 쉽게 바꿀 수 있다.

todo1.A='No....'
todo1.nothing()
To Do List
Are you done? No....

성능4: 함수 내 여러값들 동시에 쉽게 컨트롤 할 수 있다.

todo1=TODOLIST()
todo2=TODOLIST()
todo3=TODOLIST()
todo2.A="No, so I'm sad, right now."
todo2.nothing()
To Do List
Are you done? No, so I'm sad, right now.
todo3.img=Image.open('img2.jpg').resize((500,250))
todo3.title="Thank Gosh It's Monday"
todo3.Q="Really...?"
todo3.A="Thank Gosh It's funday, My number one day :)"
todo3.nothing()
Thank Gosh It's Monday
Really...? Thank Gosh It's funday, My number one day :)

성능 5: 틀의 재설계 $\star$

출력만 살짝 바꾸어서 TODOLIST2를 만들고 싶다. --> TODOLIST의 모든 내용은 그대로 가져오고, 그 살짝만 다시 조정하면 된다.

class MONDAY(TODOLIST): ## TODOLIST 라는 class를 그대로 복사!
    title="Thank Gosh It's Monday"
    Q="Really...?"
    img2=Image.open('img2.jpg').resize((500,250))
    A="Thank Gosh It's funday, My number one day :)"
    def nothing(self): ## class 안에서 정의된 함수
        print('😂😂😂'+self.title+'😂😂😂')
        display(self.img2)
        print('Squidward:  '+self.Q,'Spongebob:  '+self.A)
mon1=MONDAY()
mon1.nothing()
😂😂😂Thank Gosh It's Monday😂😂😂
Squidward:  Really...? Spongebob:  Thank Gosh It's funday, My number one day :)
mon2=MONDAY()
mon2.Q='Are you sure?'
mon2.nothing()
😂😂😂Thank Gosh It's Monday😂😂😂
Squidward:  Are you sure? Spongebob:  Thank Gosh It's funday, My number one day :)

예제를 이용한 활용

import numpy as np
class SPONGE:
    n=0
    title="Spongebob"
    def cute(self):
        self.n=self.n+1
        print(self.title)
        print(np.random.normal())
        print('귀여운 '+str(self.n)+'번째 스펀지밥')
spon1=SPONGE()
spon1.cute() # 할때마다 n이 늘어나게 만들어 놓음
Spongebob
0.3777556223500885
귀여운 3번째 스펀지밥
spon2=SPONGE()
spon2.title="Squidward"
spon2.cute()
Squidward
-0.9692155527419407
귀여운 4번째 스펀지밥
spon1.n
3
spon2.n
4

self에 들어가야했던것은 사실 인스턴스 이름지만, class 정의 시 instance 이름을 어떻게 정의될지 모르기 때문에 self로 정의된 듯 하다.

예제를 이용한 활용 2

인스턴스를 만들때마다 타이틀을 새로 정하는 방식이 있으면 좋겠다.

__init__ 함수 개발!!

__init__ 함수란?

  • 몇 가지 사항을 빼고는 별다른 특별한 점이 없는 (어떠한 마법도 없는) 그냥 함수이다.
  • 인스턴스가 생성되는 시점에 자동으로 실행된다.
  • 특별한 첫번째 인자를 가진다. (self)
  • 클래스를 인스턴스화 할때 (...)의 값들을 함수의 입력으로 받는다.
class SPONGE2:
    n=0
    def __init__(self,title):
        self.title=title
    def cute(self):
        self.n=self.n+1
        print(self.title)
        print(np.random.normal())
        print('귀여운 '+str(self.n)+'번째 스펀지밥')
spon3=SPONGE2()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-114-7e72e91f0a6b> in <module>
----> 1 spon3=SPONGE2()

TypeError: __init__() missing 1 required positional argument: 'title'
spon3=SPONGE2('Squidward')
spon3.title
'Squidward'
spon3.cute()
Squidward
-1.9003274678358142
귀여운 1번째 스펀지밥

(1) SPONGE2()를 인스턴스화 하는 순간에 __init__ 이 실행되어야함.

(2) 그런데 __init__의 첫번째 인수인 self는 입력안해도 된다고 치고, 두번째 인수인 title은 입력으로 받았어야만 하는것인데, 입력으로 받지못하여 에러메시지 발생.

(3) 도데체 그럼 언제 __init__의 두번째 인수인 title을 넣어야할까? 곰곰히 생각해보니 SPONGE2를 인스턴스화 하는 순간에 입력으로 넣었어야 논리적으로 맞다. 즉 spon3=SPONGE22('Squidward')와 같은 식으로 생성하는 순간 입력으로 넣어야 하는 것이었음.

(4) __init__의 두번째 인자가 'Squidward'로 입력되었고, 이것이 self.title 즉 spon3.title에 바로 업데이트 된 상황임.

  • 코드를 효율적으로 수정해보면?
class SPONGE2(SPONGE):
    def __init__(self,title):
        self.title=title
spon4=SPONGE2('Squidward')
spon4.cute()
Squidward
-0.7545000567411643
귀여운 1번째 스펀지밥
  • title 입력 안 해도 시행되게, 없으면 시행될 none값 작성
class SPONGE2(SPONGE):
    def __init__(self,title=None):
        self.title=title
spon5=SPONGE2()
spon5.cute()
None
-0.7622436262945875
귀여운 1번째 스펀지밥