[TIL] 클래스? 클라쓰?! 클났스!

Hyeseong·2020년 12월 17일
0

TIL

목록 보기
6/13

Class

Class를 영어사전에서 찾아보면 다음과 같은 뜻을 가지고 있습니다.

abdcv

보시다시피 굉장히 많은 뜻을 가지고 있습니다.

그 중 코딩에서 사용되는 class 라는 단어가 가지는 의미는 "부류" (위 이미지 가장 하단에 나와있는) 에 가장 가깝습니다.

그럼 "부류" 라는건 무엇일까요? 영어로는 kind, category의 의미를 가지고 있습니다.

부류를 국어사전에서 찾아보면 다음과 같은 의미들이 나옵니다.

xdf

부류의 뜻은 "동일한 범주에 속하는 대상들을 일정한 기준에 따라 나누어 놓은 갈래" 라고 국어사전에 나옵니다.

비슷한 사람들을 가리켜 "저들은 같은 부류의 사람들이다" 라고 합니다. 즉 공통점이 많은 사람들을 가리켜 "같은 부류" 라고 하는 것입니다.

예를 들어, 요즘 인기가 많은 TV 프로그램인 "전지적 참견 시점"의 출연자인 이영자, 송은이, 양세형, 유병재는 공통점이 있습니다. 바로 4명 다 코미디언 이라는 점입니다 (네, 전현무는 코미디언 이라고 하기엔 애매모호 해서 뺐습니다. 전현무, 코미디언 인가요?).

sadf

그러므로 이 4명은 같은 부류라고 할 수 있겠죠. 하지만 그렇다고 이영자, 송은이, 양세형, 유병재가 동일 인물은 절대 아닙니다. 이 4명은 개개인이 틀린 사람이지만 공통점을 가지고 있는 부류 인거죠.

sdf

즉 Comedian 이 class 가 됩니다.

그러나 comedian이라는 것은 개념일 뿐입니다.

Comedian의 실체 (instanace) 는 이영자, 송영이, 양세형, 유병재입니다.

이 실체(instance)들을 object(객체) 라고 합니다.

사람이 아닌 사물로 예를 하나 더 들어보겠습니다.

여러분이 제일 좋아하는 차는 무엇인가요?

저는 개인적으로 Lexus를 좋아합니다. (아직 가지고 있진 않습니다 😅)

Lexus, BMW, Benz, Hyundai 등 모두 자동차 입니다.

그럼 여기서 class 는 무엇일까요?

네, 자동차가 class 입니다.

그럼 자동차라는 개념의 실체(instance)는 무엇일까요?

네, Lexus, BMW, Benz, Hyundai 입니다.

asdf

Class 정의 하기

자 이제 그럼 앞서 본 Car class 와 obejct 들을 파이썬 코드로 구현해 보겠습니다.

먼저 class가 정의되어야 합니다.

파이썬에서 class를 선언하기 위해서는 다음과 같이 class 키워드를 사용하면 됩니다:

class ClassName:
    ...class 내용 코드들

참고로 class 이름은 각 단어의 앞글자를 대문자로 사용합니다.

예를들어, Car, Comedian 처럼 말이죠. 만일 한단어 이상으로 이루어져 있다면 밑줄(underscore) 없이 모든 단어를 다 붙이되 각 단어의 앞글자는 대문자로 해서 단어를 구분하게 됩니다. 다음 처럼 말이죠:

  • ScotchWishkey
  • SomeReallyLongClassName

Car class는 다음처럼 정의 할 수 있습니다.

class Car:
    pass

class가 정의되면, class로 부터 실체화(instantiate) 할 수 있습니다. 클래스를 실체화 하는 방법은 간단합니다. 다음과 같이 함수를 호출 하듯이 클래스도 호출 하면 됩니다.

hyundai = Car()
bmw = Car()

Car class를 실체(instance)화 한것이 hyundai와 bmw라는 객체(object) 인것입니다.

하지만 Car class는 아직 아무것도 안하는 비어있는 class 입니다.

앞서 class는 부류 라고 배웠습니다. 그리고 부류란 어떠한 공통점들을 가지고 있는 것/사람 들을 이야기 한다고 배웠습니다.

공통점이 중요한데요, 자동차라면 브랜드, 엔진의 마력, 연비 등등이 공통 요소가 될것 입니다.

이러한 공통 요소들을 class 에서 정의를 해주어야 합니다.

그럼 하나 하나씩 공통 요소들을 정의해 보겠습니다.

Class의 attribute(속성)

class에 정의되는 공통 요소들을 전문어로 class의 attribute(성질 혹은 속성) 이라고 합니다.

모든 자동차는 다음과 같은 공통 요소를 가지고 있습니다.

  • Maker (현대, BMW 등)
  • 모델명 (BMW305, 제네시스 등)
  • 마력 (horse power)

이 외에도 많겠지만 예제의 간단함을 위해서 위 3개만 고려하겠습니다.

위 3개의 속성들을 class에서 정의하기 위해서는 다음과 같이 __init__ 함수를 통해서 정의 해주면 됩니다.

(참고로 class 안에서 정의해주는 함수(function)는 function이라고 하지 않고 method 라고 합니다)

class Car:
    def __init__(self, maker, model, horse_power):
        self.maker       = maker
        self.model       = model
        self.horse_power = horse_power

init 함수의 작동 원리를 이해하는것이 복잡할 수 있습니다.

그러나 차근 차근 풀어나가면 쉽습니다. 그러니 차근 차근 풀어나가 보겠습니다.

asdf

먼저 __init__ 메소드의 이름을 자세히 보겠습니다. init 이라는 단어의 앞 뒤에 밑줄 2개가 있습니다.

이렇게 앞뒤로 밑줄 2개가 있는 메소드들을 special methods라고 합니다. 이들은 특별 취급을 받습니다.

그 중 __init__ 메소드는 class가 실체화 될때 사용되는 함수 입니다.

예를 들어:

hyundai = Car("현대", "제네시스", 500)

여기서 이미 __init__ 메소드가 호출이 됐습니다. __init__ 이라고 메소드 이름을 명확하게 명시하지는 않았지만 클래스가 실체화 될때 자동으로 __init__ 메소드가 호출이 됩니다.

asdf

자 근데 여기서 이상한점이 있습니다. 눈치 채셨나요?

네, __init__ 메소드의 parameter는 총 4개인데, 앞서 클래스를 실체화 할때는 3개만 넘겨주었습니다.

self 파라미터를 빼먹었는데요, 이 self 파라미터는 도대체 무엇이길래 빼먹는걸까요?

self를 이해하기가 조금 헷갈릴 수 있으니 잘 따라오세요!

코딩을 배울때 새로운 개념을 만나면 우리는 항상 해당 개념의 이름을 잘 이해해야 합니다.

그래야 개념 잡기가 쉽습니다.

그래서... self의 뜻은 바로 "자신" 이죠. 그래서 Myself 하면 "나 자신" 이고 yourself 하면 "너 자신"을 이야기 합니다.

그렇다면 class에서 "self" 는 누구를 말하는 걸까요? Class 자체를 말하는것은 아닐겁니다.

왜냐하면 앞서 보았듯이 class 자체는 공통점이 있는 부류를 가리키는 개념 이기 때문입니다.

반면에 self는 어떠한 실체를 가르키는 단어입니다.

그렇다면... 당연히 class에서 self는 class의 실체(instance)를 가르키겠죠!!! 🤔🤨🤩

네, self는 class의 실체(instance)인 객체(object)를 가르킵니다!

그러므로 Car class에서 "self" 는 Car class의 객체인 hyundai나 bmw를 가르키는 거죠.

그리고 클래스를 실체화 할때 파이썬이 해당 객체(self)를 자동으로 __init__ 함수에 넘겨줍니다.

자, 내용이 많은데 정리하자면:

  • init 메소드는 클래스가 실체화 될때 자동으로 호출이 된다.
  • init 메소드의 self 파라미터는 클래스가 실체화된 객체를 넘겨주어야 하며, 파이썬이 자동으로 넘겨준다.
  • init 메소드의 self 파라미터는 항상 정의되어야 있어야 하며 맨 처음 파라미터로 정의 되어야 한다 (그래야 파이썬이 알아서 넘겨줄 수 있으므로)

asdf

이제 __init__ 메소드의 호출 작동 원리에 대해서는 다 이해가 되셨죠??

asdf

그럼 이제 __init__ 메소드 안에 코드를 보겠습니다.

class Car:
    def __init__(self, maker, model, horse_power):
        self.maker       = maker
        self.model       = model
        self.horse_power = horse_power

Parameter로 넘겨진 maker, model, 그리고 horse_power 값을 동일한 이름으로 self 에 저장 하는 것을 볼 수 있습니다. 왜 저러는 거죠??

self 는 객체라고 방금 배웠습니다. 그러므로 객체에 maker, model, 그리고 horse_power를 저장하는걸 알 수 있습니다. 근데 왜 저장하는 걸까요?

저장하는 이유는 나중에 다시 사용하기 위해서 입니다.

더 자세히 이야기하면 다른 메소드에서 사용하기 위함입니다!

Class Method

클래스에서 __init__ 말고도 다른 메소드를 원하는 대로 추가할 수 있습니다.

Method와 attribute(속성)의 차이는 명사와 동사의 차이라고 생각하시면 됩니다.

속성은 해당 객체의 이름 등의 정해진 성질인 반면에 메소드는 move, eat 등 객체가 행할 수 있는 어떠한 action같은 느낌이라고 생각할 수 있습니다.

그럼 자동차가 할 수 있는 action은 무엇이 있을까요?

움직이기, 멈추기, 경적 울리기 등이 있을 수 있습니다.

그럼 "경적 울리기"를 메소드로 추가해 보겠습니다.

class Car:
    def __init__(self, maker, model, horse_power):
        self.maker       = maker
        self.model       = model
        self.horse_power = horse_power

    def honk(self):
        return "빠라바라빠라밤"

honk 메소드에도 self 가 들어가 있는걸 볼 수 있습니다.

모든 메소드에는 self 파라미터가 첫번째 파라미터로 들어가야 합니다.

honk 함수는 다음 처럼 사용할 수 있습니다.

hyundai = Car("현대", "제네시스", 500)
hyundai.honk()
> "빠라바라빠라밤"

네 이렇게 객체에서 메소드를 사용할때는 dot(.) 을 사용하여 객체를 호출 합니다. 즉

<객체>.<메소드>

이를 dot notation 이라고 합니다. 이미 많이 보셨을 겁니다.

자, 근데 이제 우리나라 법이 바뀌어서 모든 차는 경적소리에 해당 차의 회사명이 들어가야 한다고 합시다.

예를 들어, 현대차이 경적소리에는 "현대 빠라바라빠라밤" 이라고 나야 합니다.

근데 honk 메소드에서 해당 객체의 회사 정보를 어떻게 알 수 있을까요?

다행히도 __init__ 메소드에서 self 객체에 해당 정보들을 저장해 놓았기 때문에 다음처럼 사용하면 됩니다.

class Car:
    def __init__(self, maker, model, horse_power):
        self.maker       = maker
        self.model       = model
        self.horse_power = horse_power

    def honk(self):
        return f"{self.maker} 빠라바라빠라밤"
hyundai = Car("현대", "제네시스", 500)
hyundai.honk()
> "현대 빠라바라빠라밤"

asdf

(참고로 빠라바라바라밤 은 90년도때 오토바이 소리로 유명했습니다)

Class는 어디다 쓰나요?

지금까지 클래스에 대해서 배워봤습니다.

근데 클래스는 언제, 어떻게 쓰는걸까요?

사실 클래스 없이도 코드를 구현할 수 있습니다.

하지만 클래스를 쓰는 이유는, 클래스를 사용하면 코드의 구조를 더 효과적으로 구현할 수 있기 때문입니다.

앞서 본 Car 의 예제 코드를 class를 사용하지 않고 구현한다고 생각해보세요. 어떻게 구현할 수 있을까요?

네, 벌써 머리가 아프죠?

asdf

이렇게 코드를 클래스 위주로 작성하는 것을 object oriented programming(객체 지향 프로그래밍) 이라고 합니다. 개발자들이 많이 사용하는 단어 이니 기억해두시길 바랍니다.

Assignment

Class 를 직접 구현해 보겠습니다.

Database 라는 이름의 class를 구현해 주세요.

Database 클래스 내부에 다음의 속성(attribute)들을 선언해주세요.

  • name : database의 이름
  • size : 저장할 수 있는 데이터의 max 사이즈. Size를 넘어서는 데이터를 저장할 수 없다.

Database 클래스 내부에 다음의 메소드들을 구현해주세요.

  • insert
  • select
  • update
  • delete

각 메소드들에 대한 설명은 아래와 같습니다.

Insert

insert 메소드는 self 외에 2개의 parameter를 받습니다.

field와 value 입니다.

Field 는 저장하고자 하는 데이터의 필드명 이고 value는 값입니다.

Field 와 value는 내부적으로 dictionary에 저장되어야 합니다.

insert 메소드는 다음 처럼 호출 할 수 있습니다.

# 객체 이름이 db 라는 가정하에
db.insert("name", "정우성")

insert 메소드는 특별한 리턴값은 없습니다.

만일 내부 dictionary의 총 사이즈가 database 클래스의 size 속성보다 크면 더이상 새로운 값들을 저장하지 말아야 합니다.

Select

select 메소드는 self 외에 1개의 parameter를 받습니다.

field 입니다.

Field 는 읽고자 하는 데이터의 필드명 입니다.

내부적으로 데이터를 저장하고 있는 dictionary에서 해당 field에 해당하는 키와 연결되어 있는 값을 리턴해주어야 합니다.

예를 들어, 이미 name이라는 필드명으로 "정우성" 이라는 값을 저장했다고 한다면:

# 객체 이름이 db 라는 가정하에
db.select("name")
> "정우성"

이 되어야 합니다.

만일 해당 필드값으로 저정되어 있는 값이 없다면 None 을 리턴해주세요.

Update

Self 외에 2개의 parameter를 받습니다.

field와 value 입니다.

이름 그대로 이미 저장되어 있는 값을 수정하는 메소드 입니다.

# 객체 이름이 db 라는 가정하에
db.update("name", "아이유")

만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.

그리고 특별한 리턴 값은 없습니다.

Delete

delete 메소드는 self 외에 1개의 parameter를 받습니다.

field 입니다.

Field 는 지우고자 하는 데이터의 필드명 입니다.

# 객체 이름이 db 라는 가정하에
db.delete("name")

만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.

그리고 특별한 리턴 값은 없습니다.

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글